Я использую Thrust для некоторых задач на работе и обнаружил, что при создании zip_iterator
существует максимальное количество итераторов.
Например
#include <thrust/iterator/zip_iterator.h>
#include <thrust/device_vector.h>
int main() {
thrust::device_vector<int> A(10),B(10),C(10);
auto zitor = thrust::make_zip_iterator(A.begin(),A.begin(),
B.begin(),B.begin(),
B.begin(),B.begin(),
B.begin(),B.begin(),
C.begin(),C.begin());
}
Этот код успешно компилируется. Но если я добавлю еще один итератор в список инициализации, произойдет ошибка:
multizip.cu(8): error: no instance of overloaded function "thrust::make_zip_iterator" matches the argument list
argument types are: (thrust::detail::normal_iterator<thrust::device_ptr<int>>, thrust::detail::normal_iterator<thrust::device_ptr<int>>, thrust::detail::normal_iterator<thrust::device_ptr<int>>, thrust::detail::normal_iterator<thrust::device_ptr<int>>, thrust::detail::normal_iterator<thrust::device_ptr<int>>, thrust::detail::normal_iterator<thrust::device_ptr<int>>, thrust::detail::normal_iterator<thrust::device_ptr<int>>, thrust::detail::normal_iterator<thrust::device_ptr<int>>, thrust::detail::normal_iterator<thrust::device_ptr<int>>, thrust::detail::normal_iterator<thrust::device_ptr<int>>, thrust::detail::normal_iterator<thrust::device_ptr<int>>)
1 error detected in the compilation of "multizip.cu".
Принимает ли он не более десяти итераторов, или я что-то не понимаю? Если да, есть ли обходные пути?
using Itor = thrust::device_vector<int>::iterator;
using Zitor = thrust::zip_iterator<thrust::tuple<
Itor,Itor,Itor,Itor,Itor,Itor,
Itor,Itor,Itor,Itor,Itor>>;
Этот фрагмент кода тоже не работает, если я его не удалю Itor
, информация об ошибке:
multizip.cu(17): error: too many arguments for class template "thrust::tuple"
Поэтому я считаю, что максимальное количество итераторов в тяге::tuple действительно ограничено 10. Могу ли я преодолеть это ограничение?
@Jarod42 Я использую стандарт C++20, nvidia hpcsdk 23.3, с CUDA 12.0 и g++ версии 11.4.
Проверьте подпись из <thrust/iterator/zip_iterator.h>
В документации Thrust указано, что существует ограничение в 10. q.v. nvidia.github.io/cccl/thrust/api/structthrust_1_1tuple.html
@RobertCrovella Хорошо... Как вы думаете, есть ли обходной путь для компиляторов более низких версий?
@RobertCrovella Я думаю, что создать zip-итератор из zip-итераторов может быть хорошей идеей, спасибо!
@RobertCrovella С другой стороны, если вы используете, например. RAPIDS автоматически загрузит и будет использовать версию CCCL, от которой он зависит, независимо от используемой версии CTK. А в файле readme CCCL говорится: «Пользователям, которые хотят оставаться на переднем крае разработки CCCL, рекомендуется использовать CCCL с GitHub. Поддерживается использование более новой версии CCCL со старой версией CUDA Toolkit, но не другой. в обход». Так что он официально поддерживается, что бы это ни значило в отношении тестирования.
У них даже есть целый раздел о совместимости CTK.
Не пытаясь изменить свое мнение. Это просто звучало так, будто использование более нового CCCL было каким-то экспериментальным хаком. Это, конечно, делается на производстве. Независимо от того, хорошая это идея или нет. Вчера я сообщил о проблеме с CCCL, поэтому я очень хорошо знаю, что даже использование CCCL, поставляемого с CTK, естественно, не является «неограниченной гарантией или ожиданием успеха»;)
Что касается тестирования, то это можно узнать, посмотрев соответствующую матрицу тестирования. Старые версии CTK, особенно самая старая из поддерживаемых в настоящее время, тестируются, но лишь некоторые из них, и не так тщательно (например, меньше комбинаций с хост-компиляторами), как текущая версия. Текущая версия по-прежнему 12.5 вместо 12.6, что говорит о том, что тестирование 12.6 с поставляемым CCCL проводится отдельно и, возможно, даже более тщательно.
Ближайшая проблема, с которой вы столкнулись, заключается в том, что до недавнего времени в zip_iterator у тяги было ограничение шаблона в 10 элементов (итераторов).
Недавно (по всей видимости, при переходе с CUDA 12.3 на CUDA 12.4) конструкция zip_iterator изменилась и теперь позволяет использовать более 10 итераторов при построении zip_iterator. Таким образом, одним из вариантов может быть обновление версии вашего набора инструментов CUDA до 12.4.1 или более поздней версии.
Другой связанный вариант — обновить только тягу. В последних версиях Thrust для этого предусмотрен определенный путь совместимости. Я не привожу здесь полный рецепт, но, в двух словах, предполагая, что вы находитесь в пределах определенного пути совместимости, вы должны клонировать текущий репозиторий на своем компьютере, а затем изменить свои включения, чтобы они указывали на эту копию. Thrust — это библиотека шаблонов/заголовков, поэтому для нее не требуется отдельный этап компиляции или какие-либо другие этапы установки.
В зависимости от ваших потребностей, оставаясь в пределах лимита в 10 итераторов, как в старых версиях, вы можете создать zip_iterator из zip_iterators. Вот тому пример. Это можно использовать для получения более 10 итераторов, хотя и во вложенном порядке.
(Спасибо @paleonix за информацию о совместимости с Thrust, как указано в комментариях под вопросом.)
Какая версия? более старая версия может использовать перегрузку с жестко закодированным ограничением, тогда как «последняя» (C++11) версия может использовать переменный шаблон, поэтому в основном ограничений нет.