如何正确使用anaconda加速GPU

时间:2015-06-14 19:59:59

标签: numpy python-3.4 anaconda numba-pro

我正试图通过anaconda加速快速计算矩阵。我从非常基本的例子开始:乘以2个矩阵。

我的目标是以某种方式获得比通常更好的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实现已经很好地优化了,但我预计anaconda的官方例子会很好。我正在使用 python 3.4.3 ,并且在使用这两个帮助库时遇到错误:http://www.cs.toronto.edu/~tijmen/gnumpy.htmlhttps://github.com/rctn/gpupy

我应该说使用gpupy我在python 2.7上成功加速。

所以我的问题是:如何通过GPU使用矩阵乘法比numpy-CPU更好? anaconda官方示例有什么问题,如果有一个python3的工作库允许以坎坷的方式使用GPU?

===

结果

不幸的是,python 3并没有简单而好的方法,而是使用2.7而不是

感谢@rth for recommendedint awesome library scikits.cuda

Available functions

一些基准测试(使用anaconda mkl测试,所以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

1 个答案:

答案 0 :(得分:3)

您应该看看BLAS实现,它们为经典线性代数运算提供高度优化的例程。使用gemm函数执行密集矩阵的乘法。

  • 例如,如果针对优化的BLAS实现(OpenBLAS,ATLAS,MKL等)编译,则numpy中的矩阵乘法会得到显着改善。
  • 对于GPU,NVIDIA提供cuBLAS实现。根据这个answer,可以使用scikits.cuda模块使用numpy数组调用它。您正在使用的Anaconda accelerate也提供与cuBLAS的直接绑定。
顺便说一下,如果你想对矩阵乘法的CPU和GPU性能进行基准测试,你还应该指定Numpy用于CPU计算的BLAS,因为结果可能有一个数量级的差异(参见this benchmark