Я расширяю пример изучения параметров из odint boost, используемого с тягой, и я не знаю, как пройти вектор значений для конструктора наблюдателя, так что эти значения могут быть доступны (только для чтения) из функтора наблюдателя.Как передать вектор конструктору осеин-наблюдателя с осевым движением, чтобы его можно было прочитать внутри функтора
Следующий код для наблюдателя.
//// Observes the system, comparing the current state to
//// values in unchangingVector
struct minimum_perturbation_observer {
struct minPerturbFunctor
{
template< class T >
__host__ __device__
void operator()(T t) const
{
//// I would like to be able to read any member
//// of m_unchangingVector here.
}
};
// CONSTRUCTOR
minimum_perturbation_observer(size_t N, state_type unchangingVector, int len) :
m_N(N),
m_output(N),
m_unchangingVector(len) // len is the correct length of unchangingVector
{
// all trials start with output = 0
thrust::fill(m_output.begin() , m_output.end() , 0.0);
// copy unchangingVector to m_unchangingVector, the latter
// of which should be accessible from the functor operator()
// above.
thrust::copy(unchangingVector.begin(), unchangingVector.end(),
m_unchangingVector.begin());
}
template< class State >
void operator()(State x , value_type t)
{
thrust::for_each(
thrust::make_zip_iterator(thrust::make_tuple(
boost::begin(x) + 0*m_N,
boost::begin(x) + 1*m_N,
boost::begin(m_output)
)
),
thrust::make_zip_iterator(thrust::make_tuple(
boost::begin(x) + 1*m_N,
boost::begin(x) + 2*m_N,
boost::begin(m_output) + m_N
)
) ,
minPerturbFunctor());
}
// variables
size_t m_N; // number of trials (i.e. number of initial conditions)
state_type m_output; // of length N_ICS
state_type m_unchangingVector; //
};
Я экспериментировал с созданием m_unchangingVector static
или const
, но это не правильно, так как он должен быть установлен на конкретизации наблюдателя.
В качестве альтернативы, возможно, лучший способ сделать это - передать unchangingVector в качестве еще одного аргумента в пределах thrust::make_zip_iterator(thrust::make_tuple(...
, но я чувствую, что эти элементы будут проиндексированы так, как это будут переменные состояния (что не было бы тем, что я хочу). Один ответ, который может помочь, будет объяснением того, что (T t) означает в объявлении функтора, и как я мог бы передать unchangingVector как один и тот же объект для каждого потока, который оценивает оператор.
Я думаю, что это может быть просто вопрос выбора дескрипторов переменной ключевого слова, но я не знаю, какой из них использовать, и я не уверен, как его искать/понять ,
Ошибка, которую я получаю за код выше, составляет error: a nonstatic member reference must be relative to a specific object
. Брошено, когда я пытаюсь получить доступ к m_unchangingVector в функторе.
После дальнейших исследований, я чувствую, что я определил правильный способ выполнения этой задачи, но я все еще застрял.
Я добавил конструктор к функтору.
struct minPerturbFunctor
{
minPerturbFunctor(state_type unchangingVector, int len) :
f_unchangingVector(len)
{
// copy from argument to local vector (probably unnecessary, but
// getting errors about calling host-functions from device/host
// so being paranoid about trying to make sure things are device-side
thrust::copy(f_unchangingVector.begin(),
f_unchangingVector.end(),
unchangingVector.begin());
f_len = len;
};
template< class T >
__host__ __device__
void operator()(T t) const
{
// I can now access f_len here (progress!)
// But when I try to access any element via e.g.,
// f_unchangingVector[0] I get the error below
}
};
предупреждение: вызов хоста функции ("тяга :: подробно :: vector_base> :: Оператор []") из хостаустройства функции ("minimum_perturbation_observer :: minPerturbFunctor :: оператора()> «) не допускается
ERROR MESSAGE /usr/local/cuda/bin/..//include/thrust/detail/function.h(104): ошибка: вызов хоста функцию ("thrust :: device_vector> :: device_vector") от devic e Функция («тяга :: деталь :: устройство_функция :: устройство_функции») не разрешена
Что я делаю неправильно?
Я думаю, что я нашел пример, который делает то, что мне нужно, на https://github.com/boostorg/odeint/blob/master/examples/thrust/phase_oscillator_ensemble.cu. Я буду смотреть дальше и вернуться сюда. – weemattisnot
Вы можете передать инициализирующий параметр вашему функтору. Этот параметр может быть указателем, возвращаемым '.data()' для 'thrust :: device_vector'.Этот указатель затем может быть использован в функторе с использованием обычных методов указателей c для доступа к любому элементу вектора устройства внутри функтора. –
описан общий подход к передаче инициализирующего значения функтору (через его конструктор) [http://stackoverflow.com/questions/17468745/thrust-filter-by-key-value/17471046#17471046). в вашем случае у вас будет элемент данных вашей структуры, такой как 'T * a; ', и передайте инициализирующий элемент как' m_unchangingVector.data() ', грубо говоря. –