При использовании odeint с тягой я разрабатываю наблюдатель, который будет генерировать гистограмму переменных состояния, параллельно решая множество проблем с начальными условиями.
Проблемы с начальными условиями выполняются параллельно, заполняя device_vector такими данными.
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;
...
Или, выражаясь более кратко, индексация массива будет рассчитываться в соответствии с:
trajectoryIndex*N_BINS*N_VARS +varIndex*N_BINS +binIndex
... и позже этот вектор будет сведен к одной гистограмме для каждой переменной.
Парадигма, которую я видел в odeint + тяге, состоит в том, чтобы функтор оператора вызывался с использованием make_zip_iterator
и make_tuple
тяги, таким образом:
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()
);
который прекрасно работает, когда все аргументы функтора имеют одинаковую длину. Но в моем случае device_vector данных гистограммы, который должен быть заполнен, как описано выше, имеет другой размер и должен быть проиндексирован иначе, чем другие аргументы, переданные функтору (например, переменные состояния).
Немного осмотревшись, я думаю, что лучший способ сделать это — передать thrust ::counting_iterator, который предоставляет функтору индекс траектории, необходимый для заполнения матрицы гистограммы. Затем я также (очевидно) должен был бы каким-то образом предоставить указатель на матрицу гистограммы, чтобы ее можно было заполнить. Возможно, лучшим решением для предоставленияObserver_functor указателя на вектор гистограммы было бы предоставление его в качестве аргумента конструктору наблюдателя (аналогично решению еще один вопрос, который я разместил здесь).
Все это вызвало некоторую путаницу в отношении того, как работают массивы в приведенной выше парадигме make_zip_iterator
/make_tuple
, когда переданные аргументы указывают векторы разной длины.
ВОПРОСЫ:
Является ли предлагаемое мной использование
thrust::counting_iterator
и передача указателя на выходной массив через конструктор объекта функтора рекомендуемым подходом?В более общем плане, как работает описанная выше парадигма
make_zip_iterator
/make_tuple
, когда переданные аргументы указывают векторы разной длины?