Я пытаюсь получить быстрые вычисления матриц с ускорением anaconda. Я начал с очень простого примера: умножьте 2 матрицы.Как правильно использовать ускорение anaconda для GPU
Моя цель состоит в том, чтобы каким-то образом получить GPU-умножение, которое лучше, чем обычно numpy.dot
Вот мой основной пример, основанный на этом documentation.
from numbapro import guvectorize
from numpy import arange
@guvectorize(['void(float32[:,:], float32[:,:], float32[:,:])'], '(m,n),(n,p)->(m,p)', target='gpu')
def matmul(A, B, C):
m, n = A.shape
n, p = B.shape
for i in range(m):
for j in range(p):
C[i, j] = 0
for k in range(n):
C[i, j] += A[i, k] * B[k, j]
import numpy as np
import time
for dim in [50, 100, 200]:
rnd = np.random.RandomState(0)
a = rnd.rand(dim, dim).astype(np.float32)
b = rnd.rand(dim, dim).astype(np.float32)
resgpu = np.zeros_like(a)
start = time.time()
rescpu = np.dot(a, b)
print('CPU:', time.time() - start)
start = time.time()
resgpu = matmul(a, b)
print('GPU:', time.time() - start)
print(np.allclose(rescpu, resgpu))
print(np.allclose(resgpu, rescpu))
Результаты слишком плохо: GPU невероятно медленнее, чем CPU
CPU: 0.00011801719665527344
GPU: 0.05677294731140137
True
True
CPU: 0.00011205673217773438
GPU: 0.3881375789642334
True
True
CPU: 0.00038933753967285156
GPU: 3.018171787261963
True
True
Конечно, я понимаю, что реализация внутренней NumPy хорошо оптимизирован, но я ожидал анаконды официальный пример, чтобы быть хорошим. Я использую питон 3.4.3 и получил ошибки с помощью этих двух помогая LIBS: http://www.cs.toronto.edu/~tijmen/gnumpy.html и https://github.com/rctn/gpupy
Я должен сказать, что с gpupy я был успешным на ускорение питона 2.7.
Итак, мой вопрос: как получить матричное умножение лучше, чем numpy-CPU, используя GPU? Что не так с официальным примером anaconda и если есть рабочая библиотека для python3, которая позволяет использовать графический процессор в несколько раз?
===
РЕЗУЛЬТАТЫ
К сожалению, нет простой и хороший способ для Python 3, используйте 2.7 вместо
Благодаря @rth для recommendint удивительной библиотеки scikits.cuda
Некоторые ориентиры (Проверено с помощью анаконды МКЛ, так NumPy быстро тоже)
dim = 10000
rnd = np.random.RandomState(0)
a = rnd.rand(dim, dim).astype(np.float32)
b = rnd.rand(dim, dim).astype(np.float32)
a_gpu = gpuarray.to_gpu(a)
b_gpu = gpuarray.to_gpu(b)
start = time.time()
rescpu = np.dot(a, b)
print 'CPU:', time.time() - start
start = time.time()
resgpu = culinalg.dot(a_gpu, b_gpu)
print 'GPU:', time.time() - start
resgpu = resgpu.get()
print np.allclose(rescpu, resgpu)
print np.allclose(resgpu, rescpu)
И результаты
CPU: 16.4765479565
GPU: 0.000520944595337
Обратите внимание, что копирование данных с и из графического процессора является дорогостоящим. Поэтому 'gpuarray.to_gpu' должен находиться внутри раздела с таймированием, а затем я полагаю, что время GPU будет немного выше. – rth
Глядя на ваши тайминги, я подозреваю, что culinalg.dot работает асинхронно, т. Е. Вам нужно синхронизировать(), в противном случае графический процессор все еще вычисляет во время вашего отчета «GPU:». С вашими размерами, я получаю улучшение в 5 раз на GPU (Tesla K40, работает в 600 мс без передачи данных) по сравнению с CPU (MKL, 28 ядер). В отличие от вашей установки, я использую numbapro.cudalib.Blas и do numba.cuda.synchronize(). –