проблема в том, что вы не суммируете весь набор блоков. У вас есть векторное измерение 10000000 и 512 потоков, что означает, что вам нужно сложить по всем блокам 19532 блоков. Это достигается в стандартном языке CUDA путем запуска нескольких ядер (в основном для старых устройств) или с помощью атомарных операций. В частности, ваша проблема в этой части вашего кода:
if pos < const_array.shape[0]:
sbuf[tx] = const_array[pos] # do the computation cuda.syncthreads()
if cuda.threadIdx.x == 0:
for i in range(bw):
res_array[0] += sbuf[i]
В первых двух строках вы копируете данные из глобальной памяти в общую память массива sbuf. Но затем все потоки в разных блоках одновременно пытаются добавить свои локальные данные в глобальный адрес памяти по адресу res_array, это не является последовательным, и разные потоки могут просто считывать одни и те же данные дважды и давать неправильные результаты. Решение состоит в том, чтобы сначала выполнить частичную сумму в разделяемой памяти, а затем выполнить атомарную сумму, чтобы избежать асинхронных операций чтения-записи
if cuda.threadIdx.x == 0:
sum = 0
for i in range(bw):
sum += sbuf[i]
cuda.atomic.add(res_array, 0, sum)
, которые должны решить вашу проблему.
С уважением.