こんにちは、高速な行列の乗算、加算、function_overwrite、および軸の削減による合計を実行し、RAM なしで CPU を介して numpy.memmaps で作業するのに問題があります (私は思います)。numexpr を使用する場合にのみ、ドットから配列を作成することを避けることができます。
For example:
a=np.require(np.memmap('a.npy',mode='w+',order='C',dtype=np.float64,shape=(10,1)),requirements=['O'])
b=np.memmap('b.npy',mode='w+',order='C',dtype=np.float64,shape=(1,5))
c=np.memmap('c.npy',mode='w+',order='C',dtype=np.float64,shape=(1,5))
#func -> some method, like i.e. sin()
#in numexpr it will be simple
ne.evaluate('sum(func(b*a+c),axis=1)')
#in numpy with einsum it will have to be with creating additional out-of-dot handling array
d=np.require(np.memmap('d.npy',mode='w+',order='C',dtype=np.float64,shape=(10,5)),requirements=['O'])
np.einsum('ij,kj->ki',b,a,out=d)
d+=c
func(d,out=d)
np.einsum('ij->i',d,out=c)
RAMなしでCPUを使用してnumexprよりも高速に実行することは可能ですか? Cython + FORTRAN の lapack や blass はどうですか? ヒントやコツは大歓迎です!助けてくれてありがとう!
編集された情報: ちなみに、Intel Core2Duo t9300 CPU、2.7 GB RAM(BIOSの問題により4GBからのみ表示されます)、SSD 250GB、古いIntel GPUを搭載したラップトップで作業しています。いくつかのアドオンを含む Firefox で主に使用される RAM のレベルが低いため、コーディング用のスペースがあまり残っていないため、xD の使用を避けています。
そして、私はプログラミングの上級レベル (ステップ 1/1000) にいるように感じますが、今のところコードがハードウェア上でどのように機能するかはわかりません - 私はそれを推測しているだけです (したがって、私の考えのいくつかの間違いは xD に見えるかもしれません)。
編集: numexpr と cython prange for-loop を使用して正弦波を計算するコードを cython で作成しました。
脈動データ (om、eps、Spectra、Amplitude) は OM numpy.memmap に保存され、時間データ (t、z) は TI numpy.memmap に保存されます。OM は (4,1,2500) のような形で、TI は (2,1,5e+5,1) のような形です。その形で必要なだけです。
cdef inline void sine_wave_numexpr(OM,TI,int num_of_threads):
cdef long m,n=10
cdef Py_ssize_t s=TI.shape[2]/n
cdef str ex_sine_wave=r'sum(A*sin(om*ti+eps),axis=1)'
cdef dict dct={'A':OM[3],'om':OM[0],'eps':OM[2]}
for m in range(n):
sl=slice(s*m,s*(m+1))
dct['ti']=TI[0,0,sl]
evaluate(ex_sine_wave,
global_dict=dct,
out=TI[1,0,sl,0])
cdef inline void sine_wave_cython(double[:,:,::1]OM,double[:,:,:,::1]TI,int num_of_threads):
cdef int i,j
cdef Py_ssize_t n,m
cdef double t,A,om,eps
n=OM.shape[2]
m=TI.shape[2]
for i in prange(m,nogil=True,num_threads=num_of_threads):
t=TI[0,0,i,0]
for j in prange(n,num_threads=num_of_threads):
A=OM[3,0,j]
om=OM[0,0,j]
eps=OM[2,0,j]
TI[1,0,i,0]+=A*sin(om*t+eps)
cpdef inline void wave_elevation(double dom,OM,TI,int num_of_threads, str method='cython'):
cdef int ni
cdef double i,j
cdef Py_ssize_t shape=OM.shape[2]
numexpr_threads(num_of_threads)
OM[2,0]=2.*np.random.standard_normal(shape)
evaluate('sqrt(dom*2*S)',out=OM[3],
local_dict={'dom':dom,'S':OM[1]})
if method=='cython':
sine_wave_cython(OM,TI,num_of_threads)
elif method=='numexpr':
sine_wave_numexpr(OM,TI,num_of_threads)
TI.shape=TI.shape[:3]
Cython を使い始めたばかりなので、最適化されていない可能性があります。今のところ、prange を使用したコードは numexpr と同じ時間がかかっています (この部分を含むすべてのコードの RAM 使用量は 100 MB、CPU は 50%、SSD は低 - 計算時間は 1-2 分です)。私はmemoryviewsを試しましたが、それはいくつかのローカルコピーを作成し、時間の経過とともにRAMを使用しました。メモリビューの操作方法を理解するには、上級レベルのステップ 3/1000 である必要があります。