当前位置: 首页 > 面试题库 >

使用SciPy接口和Cython直接调用BLAS / LAPACK

淳于禄
2023-03-14
问题内容

此处有一篇文章:https :
//gist.github.com/JonathanRaiman/f2ce5331750da7b2d4e9,通过仅调用Fortran库(BLAS /
LAPACK / Intel MKL / OpenBLAS
/随NumPy一起安装的任何库),都显示了极大的速度改进。经过数小时的研究(由于不建议使用的SciPy库),我终于得到了编译,但没有结果。它比NumPy快2倍。不幸的是,正如另一个用户指出的那样,Fortran例程始终将输出矩阵添加到计算出的新结果中,因此它仅在第一次运行时与NumPy相匹配。即A := alpha*x*y.T + A。因此,这仍然需要快速解决。

[更新:对于那些想要使用SCIPY接口的人,请点击这里https://github.com/scipy/scipy/blob/master/scipy/linalg/cython_blas.pyx,因为它们已经对BLAS
/ LAPACK进行了优化在CPDEF声明中,只需复制/粘贴到您的cython脚本中,# Python-accessible wrappers for testing: 也可以在cython_lapack.pyx上方的链接上找到,但没有Cython测试脚本]

import numpy as np;
from cyblas import outer_prod;
a=np.random.randint(0,100, 1000);
b=np.random.randint(0,100, 1000);
a=a.astype(np.float64)
b=b.astype(np.float64)
cy_outer=np.zeros((a.shape[0],b.shape[0]));
np_outer=np.zeros((a.shape[0],b.shape[0]));

%timeit outer_prod(a,b,cy_outer)
#%timeit outer_prod(a,b) #use with fixed version instead of above line, results will automatically update cy_outer
%timeit np.outer(a,b, np_outer)
100 loops, best of 3: 2.83 ms per loop
100 loops, best of 3: 6.58 ms per loop

#结束测试脚本

用于编译cyblas.pyx的PYX文件(主要是np.ndarray版本)

import cython
import numpy as np
cimport numpy as np

from cpython cimport PyCapsule_GetPointer 
cimport scipy.linalg.cython_blas
cimport scipy.linalg.cython_lapack
import scipy.linalg as LA

REAL = np.float64
ctypedef np.float64_t REAL_t
ctypedef np.uint64_t  INT_t

cdef int ONE = 1
cdef REAL_t ONEF = <REAL_t>1.0

ctypedef void (*dger_ptr) (const int *M, const int *N, const double *alpha, const double *X, const int *incX, double *Y, const int *incY, double *A, const int * LDA) nogil
cdef dger_ptr dger=<dger_ptr>PyCapsule_GetPointer(LA.blas.dger._cpointer, NULL)  # A := alpha*x*y.T + A

cpdef outer_prod(_x, _y, _output):
#cpdef outer_prod(_x, _y): #comment above line & use this to use the reset output matrix to zeros
    cdef REAL_t *x = <REAL_t *>(np.PyArray_DATA(_x))
    cdef int M = _y.shape[0]
    cdef int N = _x.shape[0]
    #cdef np.ndarray[np.float64_t, ndim=2, order='c'] _output = np.zeros((M,N)) #slow fix to uncomment to reset output matrix to zeros
    cdef REAL_t *y = <REAL_t *>(np.PyArray_DATA(_y))
    cdef REAL_t *output = <REAL_t *>(np.PyArray_DATA(_output))
    with nogil:
        dger(&M, &N, &ONEF, y, &ONE, x, &ONE, output, &M)

非常感激。希望这可以为其他人节省一些时间(ALMOST可以工作)-实际上,正如我所说的,它可以工作1倍并匹配NumPy,然后每个后续调用都将再次添加到结果矩阵中。如果我将输出矩阵重置为0并重新运行结果,则匹配NumPy。奇怪…尽管如果不加注释,上面的几行即使在NumPy速度下也可以工作。已经找到了替代方法memset,并将在另一篇文章中…我只是还没有弄清楚确切的称呼方法。


问题答案:

据netlib
dger(M, N, ALPHA, X INCX, Y, INCY, A, LDA)执行A := alpha*x*y**T + A。所以A应该是全部为零得到的外积XY



 类似资料:
  • 4.2 接口调用 Camel管理端定义了两个版本的接口。第一版接口路径以"/api/"开头,第二版接口路径以"/api/v2"开头。 两个版本接口的主要区别在于:第二版本接口将更改配置、发布配置文件这两部操作聚合成为一个原子操作。则调用第二版本接口,如果成功,则Nginx当前配置为更改之后的配置;如果失败,则Nginx当前配置为调用接口之前的配置。不会出现不安全的中间状态。 第一版本接口: 更新节

  • 一般在开始使用tendermint之前, 作为开发者应该最关心的就是abci接口了, 因为这个是和tendermint进行交互的关键。 个人觉得这个也是tendermint的优势之一。 有了这个接口定义才有了实现通用区块链平台的可能。 所以说如果作为一个开发者, 不想了解整个tendermint的流转流程, 只想实现自己特定功能的区块链, 那么这一篇文章至少是应该看得。 我会从客户端创建开始说起,

  • TOP api 是 淘宝开放平台提供的api。 完善的top api列表参考:http://open.taobao.com/docs/api_list.htm 要在插件中调用Top接口,需引入QAP-SDK 模块。 以下演示调用taobao.time.get接口获取数据的情况。 /** @jsx createElement */ import {createElement, Component}

  • 主要内容:1.Aware是什么时候赋值进来的,2.Aware接口的作用,3.Aware接口如何调用,4.测试,5.执行流程Aware接口是利用的回调机制, 将资源注入ioc容器 1.Aware是什么时候赋值进来的 1.createBeanInstance实例化 bean 2.populateBean属性注入 3.initializingBean初始化对象 createBeanInstance:getBean -> doGetBean -> createBean -> doCreateBean i

  • LFMultipleLivenessManager 调用流程 LFMultipleLivenessManager 是对LFMultipleLivenessController 调用流程进一步的封装,方便用户直接调用 1 初始化 LFMultipleLivenessManager 输入token token LFMultipleLivenessManager *manager = [[LFMulti

  • 1.初始化 创建LFLivenessSDK对象detector,具体传参请查看demo /** * 获取token * 强烈建议:appID不要放在客户端 */ private void requestToken() { } 设置参数,开启人脸识别 /** * 开始人脸识别 */ LFLivenessBu