Comment utiliser correctement anaconda accélérer le GPU

Je suis en train d'essayer d'obtenir très rapidement des calculs de matrices avec un anaconda s'accélérer. J'ai commencé avec un exemple très simple: multiplier de 2 matrices.

Mon but est d'obtenir en quelque sorte GPU multiplication qui est mieux que d'habitude numpy.dot

Voici mon exemple de base, fondée sur ce la 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))

Les résultats sont trop mauvais: le GPU est incroyablement plus lent que le 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

Bien sûr, je comprends que interne numpy réalisation est bien optimisé, mais je m'attendais à anaconda officiel de l'exemple pour être bon. Je suis à l'aide de python 3.4.3 et eu des erreurs avec l'aide de ces deux aider les libs: http://www.cs.toronto.edu/~tijmen/gnumpy.html et https://github.com/rctn/gpupy

Je dois dire qu'avec gpupy j'avais réussi speedup sur python 2.7.

Donc ma question est: comment puis-je obtenir multiplication de matrice de mieux que numpy-CPU en utilisant des GPU? Quel est le problème avec anaconda officiel de l'exemple et si il y a un travail de la bibliothèque pour python3 qui permet d'utiliser le GPU dans numpy?

===

RÉSULTATS

Malheureusement, il n'est pas simple et de bon sens pour python 3, l'utilisation de 2,7 au lieu

Grâce à @rd pour recommendint génial bibliothèque scikits.cuda

Les fonctions disponibles

Certains de référence (testé avec l'aide de l'anaconda mkl, donc numpy est trop rapide)

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)

Et les résultats

CPU: 16.4765479565
GPU: 0.000520944595337
Notez que la copie de données vers et à partir de GPU est coûteux. Donc gpuarray.to_gpu doit être à l'intérieur de la temporisation de l'article, et puis je suppose que le GPU sera un peu plus élevé.
En regardant votre timings, je soupçonne que le culinalg.dot est en cours d'exécution asynchrone, c'est à dire que vous devez synchroniser(), sinon le GPU est encore le calcul lors de votre impression de " GPU:' instruction. Avec vos tailles, je reçois un ~5 fois meilleur sur le GPU (Tesla K40, courses en 600 ms SANS les transferts de données) par rapport à l'UC (MKL, 28 cœurs). Contrairement à votre configuration, je suis en utilisant numbapro.cudalib.Blas et ne numba.cuda.synchronize().

OriginalL'auteur budmitr | 2015-06-14