Разобрался по-быстрому с PyOpenCL, написал несколько рабочих кернелов. По ходу дела возникли вопросы, ответы на которые не смог нагуглить
1. Перед вызовом кернела массив входных данных преобразуется в CL-специфичный объект input_buf = cl.Buffer(...), который далее передается аргументом при вызове кернела. Происходит ли копирование входных данных в память GPU однократно при вызове cl.Buffer, или многократно при каждом вызове кернела? Если многократно - как сделать, чтобы эти данные копировались один раз и лежали там все время работы программы?
2. Во всех примерах, которые я нашел, кернел возвращает массив, количество элементов которого пропорционально количеству воркеров, т. е. каждый поток дает какой-то независимый частный результат, а хост-программа забирает массив этих результатов. Мне же нужно единое булево значение, т. е. если в одном из воркеров получается true, то он должен остановить остальные воркеры, записать 1 в общую переменную, изначально выставленную в 0, и завершиться сам. Можно ли сделать нечто подобное, чтобы не перебирать массив булевых значений в хост-программе?
3. Почему при запуске кернела вместо просто целочисленного числа потоков указываются какие-то local worksize и global worksize с размерностями? В чем их суть или где найти подробное объяснение? Я в своем просто указал global = (количество_элементов), local = None, массив сделал плоским, в кернеле сделал вычисление смещений с номером воркера для доступа к элементам конкретного экземпляра. Работает, хотя не уверен, что эффективно. Сколько потоков может на самом деле выполнять GPU? Что происходит, если пытаются запустить больше?
4. Как реализовать схему «для N объектов запускаются по M воркеров, до определенной точки алгоритма работают параллельно, далее из каждых M остается по 1-му, делающему что-то с M значениями, итого N»? Надеюсь, понятно сформулировал.