numpy相关系数:导致seg故障的大型阵列上的np.点(A,A.T)
注: 我有一个大数组a:numpy相关系数:导致seg故障的大型阵列上的np.点(A,A.T),numpy,blas,dot-product,Numpy,Blas,Dot Product,注: 我有一个大数组a: Speed is not as important as getting a final result. However, some speed up over worst case is required as well. 我需要计算相关系数 A.shape=(20000,265) # or possibly larger like 50,000 x 265 我只是借用了他们的代码,编写了我自己的cov/corr,而不是转换成双精度,因为我真的只需要32位浮点。
Speed is not as important as getting a final result.
However, some speed up over worst case is required as well.
我需要计算相关系数
A.shape=(20000,265) # or possibly larger like 50,000 x 265
我只是借用了他们的代码,编写了我自己的cov/corr,而不是转换成双精度,因为我真的只需要32位浮点。我抛弃了conj(),因为我的数据总是真实的
np.corrcoeff # internally casts the results as doubles
我的内存仍然不足,我使用的是一台大内存机器,264GB
有人告诉我,FastC库可能正在使用一个打破常规的例程
将产品点成几块,为了优化这一点,元素的数量被填充为2的幂
我真的不需要计算相关系数矩阵的对称部分。
但是,我看不到一种方法可以在合理的时间内通过python循环“手动”完成这项工作
有人知道有什么方法可以让numpy获得一个像样的点积例程,它可以平衡内存使用和速度
干杯
更新:
有趣的是,写这些问题往往能帮助我找到更好的谷歌查询语言
我们发现:
cov = A.dot(A.T)/n #where A is an array of 32 bit floats
diag = np.diag(cov)
corr = cov / np.sqrt(np.mutliply.outer(d,d))
我不确定我是否遵守……因此,请评论或提供有关此解决方案的答案,您自己的想法,或只是对这类问题的一般评论
短暂性脑缺血发作
编辑:我很抱歉,因为我的数组比我想象的要大得多。
数组大小实际上是151000 x 265
我在一台264 GB的计算机上内存不足,至少有230 GB的可用空间
我很惊讶numpy调用blas dgemm并小心使用C顺序数组
没有做下蹲。您可以试试看
np.einsum
是否比dot更适合您的情况:
http://wiki.scipy.org/PerformanceTips
dot
的内部工作机制有点模糊,因为它试图使用BLAS优化例程,这有时要求数组的副本以Fortran顺序排列,不确定这里是否是这种情况einsum将缓冲其输入,并在可能的情况下使用矢量化SIMD操作,但除此之外,它基本上将运行朴素的三个嵌套循环来计算矩阵积。使用英特尔mkl编译的Python将在大约30秒内以12GB内存运行:
cov = np.einsum('ij,kj->ik', A, A) / n
如果您无法访问intel的MKL,请下载python并安装accelerate软件包,该软件包具有30天的试用版,或免费提供给学术界,其中包含MKL编译。各种其他C++ BLAS库也应该工作——即使它从C到F复制数组,也不应该占用更多的内存。
我能想到的唯一一件事是,您的安装正在尝试做的是尝试将整个50000 x 50000 x 265阵列保存在内存中,坦白说,这非常糟糕。作为参考,32 50000 x 50000阵列仅为10GB,而上述阵列为2.6TB
如果是gemm问题,您可以尝试块gemm公式:
>>> A = np.random.rand(50000,265).astype(np.float32)
>>> A.dot(A.T)
array([[ 86.54410553, 64.25226593, 67.24698639, ..., 68.5118103 ,
64.57299805, 66.69223785],
...,
[ 66.69223785, 62.01016235, 67.35866547, ..., 66.66306305,
65.75863647, 86.3017807 ]], dtype=float32)
这会更慢,但有望克服内存问题。更新:经过仔细检查,dot产品完成时没有出现错误
输出数组由151000列中95000列到末尾的零组成。
也就是说,对于所有行,out[:,94999]=非零,但out[:,95000]=0
这太烦人了
交换,提到了一些我也想过的东西…因为blas是fortran,不应该
输入的顺序是F顺序。。。?其中,如下面的scipy doc页面所示,为C订单
尝试F顺序导致分段错误。我又回到原点了
原职
我终于找到了我的问题,和往常一样在细节上
我使用的是一个np.float32数组,它存储为F顺序。据我所知,我无法控制F顺序,因为数据是使用图像库从图像加载的
def chunk_gemm(A, B, csize):
out = np.empty((A.shape[0],B.shape[1]), dtype=A.dtype)
for i in xrange(0, A.shape[0], csize):
iend = i+csize
for j in xrange(0, B.shape[1], csize):
jend = j+csize
out[i:iend, j:jend] = np.dot(A[i:iend], B[:,j:jend])
return out
这个3级blas程序就完成了。我的问题有两方面:
import scipy
roi = np.ascontiguousarray( roi )# see roi.flags below
out = scipy.linalg.blas.sgemm(alpha=1.0, a=roi, b=roi, trans_b=True)
而且。。。我用的是blas dgemm而不是sgemm。d代表double,s代表single。
请参阅此pdf:
我看了一眼就不知所措了……我回去读了维基百科关于blas例程的文章,以了解3级与其他级别的对比:
现在它在A=150000 x 265上工作,执行:
roi.flags
C_CONTIGUOUS : False
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
谢谢大家的想法…知道这是可以做到的是最重要的 谢谢Jaime,在我使用最新的研究进行测试后,我会试试你的想法。如果它能节省内存并避免seg故障,那么它就是一个解决方案。希望我也能找到一个速度相当快的解决方案…einsum看起来像预期的那样工作…缓慢但合理的内存使用。我学过物理,非常喜欢这个符号。你的numpy链接到哪个blas库np.\uuuu config\uuuu.blas\u opt\u info
@jtaylor我已经读了一些关于这个配置bf的内容,但对这个输出的含义不太自信:{'define\u macros':[('ATLAS\u info','“\\\'3.8.4\\”)],'language':'c','libraries':['ptf77blas','ptcblas ATLAS'],“我在一台有264 GB的机器上内存不足,至少有230 GB可用空间”看起来很可疑,您使用的是什么操作系统和python\numpy的哪个版本?(我是指x32或x64?)很高兴知道…将投入更多精力让MKL工作,并希望重复您的结果。THX!结果证明MKL不是我工作场所可以使用的解决方案。如果您注意到我最近的编辑,数组大小要大得多。如果您想用更大的数组再次运行sim卡,我很好奇您的结果。干杯我不明白您的注释numpy.dot
正确地选择了正确的BLAS例程DGEMM
、SGEMM
、CGEMV
,或者其他任何程序。如果您有很多零,可以使用稀疏矩阵
A \dot A.T