Я работаю с довольно большими плотными массивами с плавающей запятой, которые в настоящее время находятся на диске в PyTables CArray s. Мне нужно иметь возможность выполнять эффективные точечные продукты с использованием этих массивов, например C = A.dot(B), где A - это огромный (~ 1E4 x 3E5 float32) массив с памятью, а B и C меньше numpy массивы, которые находятся в основной памяти.
То, что я делаю в данный момент, - это копирование данных в массивы numpy с отображением памяти с использованием np.memmap, а затем вызов np.dot непосредственно на массивы с отображением памяти. Это работает, но я подозреваю, что стандартный np.dot (или, скорее, базовые функции BLAS, которые он вызывает), вероятно, не очень эффективен с точки зрения количества операций ввода-вывода, необходимых для вычисления результата.
Я нашел интересный пример в этой обзорной статье. Наивный точечный продукт, рассчитанный с использованием 3х вложенных циклов, например:
def naive_dot(A, B, C):
    for ii in xrange(n):
        for jj in xrange(n):
            C[ii,jj] = 0
            for kk in xrange(n):
                C[ii,jj] += A[ii,kk]*B[kk,jj]
    return C
требуется выполнить операции ввода/вывода O (n ^ 3).
Однако, обрабатывая массивы в блоках соответствующего размера:
def block_dot(A, B, C, M):
    b = sqrt(M / 3)
    for ii in xrange(0, n, b):
        for jj in xrange(0, n, b):
            C[ii:ii+b,jj:jj+b] = 0
            for kk in xrange(0, n, b):
                C[ii:ii+b,jj:jj+b] += naive_dot(A[ii:ii+b,kk:kk+b], 
                                                B[kk:kk+b,jj:jj+b],
                                                C[ii:ii+b,jj:jj+b])
    return C
где M - максимальное количество элементов, которые будут вписываться в память ядра, количество операций ввода-вывода сводится к O (n ^ 3/sqrt (M)).
Насколько разумным является np.dot и/или np.memmap? Вызывает ли вызов np.dot эффективный продукт с блочной точкой? Имеет ли np.memmap какое-либо причудливое кэширование, которое улучшило бы эффективность такого типа операций?
Если нет, существует ли какая-то ранее существовавшая функция библиотеки, которая выполняет эффективные точечные продукты ввода-вывода, или я должен сам попытаться реализовать ее?
Update
Я провела сравнительный анализ с ручным внедрением np.dot, который работает с блоками входного массива, которые явно считываются в память ядра. Эти данные по крайней мере частично касаются моего первоначального вопроса, поэтому я отправляю его как ответ.
