nVidia Thrust: device_ptr Const-Correctness

В моем проекте, который широко использует nVidia CUDA, я иногда использую Thrust для вещей, которые он делает очень, очень хорошо. Уменьшение - это один алгоритм, который особенно хорошо реализован в этой библиотеке, и одно из применений снижения - нормализовать вектор неотрицательных элементов путем деления каждого элемента на сумму всех элементов.

template <typename T>
void normalise(T const* const d_input, const unsigned int size, T* d_output)
{
    const thrust::device_ptr<T> X = thrust::device_pointer_cast(const_cast<T*>(d_input));
    T sum = thrust::reduce(X, X + size);

    thrust::constant_iterator<T> denominator(sum);
    thrust::device_ptr<T> Y = thrust::device_pointer_cast(d_output);
    thrust::transform(X, X + size, denominator, Y, thrust::divides<T>());
}

(T обычно float или же double)

В общем, я не хочу зависеть от Thrust во всей моей кодовой базе, поэтому я стараюсь убедиться, что функции, подобные приведенному выше примеру, принимают только необработанные указатели устройств CUDA. Это означает, что как только они скомпилированы NVCC, я могу статически связать их с другим кодом без NVCC.

Однако этот код беспокоит меня. Я хочу, чтобы функция была правильной, но не могу найти const версия thrust::device_pointer_cast(...) - Существует ли такая вещь? В этой версии кода я прибег к const_cast так что я использую const в функции подписи, и это меня огорчает.

С другой стороны, кажется странным копировать результат сокращения на хост, чтобы отправить его обратно на устройство для следующего шага. Есть лучший способ сделать это?

1 ответ

Решение

Если вам нужна постоянная корректность, вы должны быть везде правильной. input это указатель на const Tследовательно, так и должно быть X:

const thrust::device_ptr<const T> X = thrust::device_pointer_cast(d_input);
Другие вопросы по тегам