2016-10-07 4 views
0

일부 데이터를 취하는 python3 함수의 속도를 높이려고합니다.이 함수는 인덱스의 배열이며 일정한 기준을 충족하면 저장합니다. "cython -a script.py"를 사용하여 속도를 높이려고했지만 병목 목은 h5py I/O 슬라이스 데이터 세트 인 것 같습니다.cython과 h5py로 빠르게 hdf5 파일 읽기

나는 Cython에 비교적 익숙하지 않으므로, 속도를 높이거나 h5py I/O로 제한 할 수 있는지 궁금하다. h5pyHDF5c 코드와 인터페이스 cython 코드를 사용, http://api.h5py.org/ : 여기에 설명 된대로

import numpy as np 
import h5py 

cimport numpy as np 
cimport cython 
from libc.math cimport sqrt 

DTYPE64 = np.int64 
ctypedef np.int64_t DTYPE64_t 
DTYPE32 = np.int32 
ctypedef np.int32_t DTYPE32_t 

@cython.boundscheck(False) 
@cython.wraparound(False) 
def tag_subhalo_branch(np.ndarray[DTYPE64_t] halos_z0_treeindxs, 
         np.ndarray[DTYPE64_t] tree_pindx, 
         np.ndarray[DTYPE32_t] tree_psnapnum, 
         np.ndarray[DTYPE64_t] tree_psnapid, 
         np.ndarray[DTYPE64_t] tree_hsnapid, hf, 
         int size): 

    cdef int i 
    cdef double radial, progen_x, progen_y, progen_z 
    cdef double host_x, host_y, host_z, host_rvir 
    cdef DTYPE64_t progen_indx, progen_haloid, host_id 
    cdef DTYPE32_t progen_snap 
    cdef int j = 0 
    cdef int size_array = size 
    cdef np.ndarray[DTYPE64_t] backsplash_ids = np.zeros(size_array, 
                 dtype=DTYPE64) 


    for i in range(0, size_array): 
     progen_indx = tree_pindx[halos_z0_treeindxs[i]] 
     if progen_indx != -1: 
      progen_snap = tree_psnapnum[progen_indx] 
      progen_haloid = tree_psnapid[progen_indx] 

      while progen_indx != -1 and progen_snap != -1: 
       # ** This is slow ** 
       grp = hf['Snapshots/snap_' + str('%03d' % progen_snap) + '/'] 
       host_id = grp['HaloCatalog'][(progen_haloid - 1), 2] 
       # ** 

       if host_id != -1: 
        # ** This is slow ** 
        progen_x = grp['HaloCatalog'][(progen_haloid - 1), 6] 
        host_x = grp['HaloCatalog'][(host_id - 1), 6] 
        progen_y = grp['HaloCatalog'][(progen_haloid - 1), 7] 
        host_y = grp['HaloCatalog'][(host_id - 1), 7] 
        progen_z = grp['HaloCatalog'][(progen_haloid - 1), 8] 
        host_z = grp['HaloCatalog'][(host_id - 1), 8] 
        # ** 
        radial = 0 
        radial += (progen_x - host_x)**2 
        radial += (progen_y - host_y)**2 
        radial += (progen_z - host_z)**2 
        radial = sqrt(radial) 

        host_rvir = grp['HaloCatalog'][(host_id - 1), 24] 
        if radial <= host_rvir: 
         backsplash_ids[j] = tree_hsnapid[ 
          halos_z0_treeindxs[i]] 
         j += 1 
         break 

       # Find next progenitor information 
       progen_indx = tree_pindx[progen_indx] 
       progen_snap = tree_psnapnum[progen_indx] 
       progen_haloid = tree_psnapid[progen_indx] 
    return backsplash_ids 
+0

'cython'은'c'에서 동작을 수행 할 수있는 속도를 향상시킵니다. 또한'memoryviews '를 사용하여'numpy' 인덱싱을 수행 할 수 있습니다. 그러나 'h5py'색인을 만질 수는 없습니다. 그것을하기 위해서는'h5py' 함수를 호출해야합니다. 'cython'은 배열 작업으로 표현할 수없는 내부 루프에 가장 적합합니다. – hpaulj

답변

1

: 여기

내가 개선하기 위해 노력하고있어 기능입니다. 따라서 자신의 cython 코드에서 직접 액세스 할 수 있습니다. 그러나 나는 더 많은 연구가 필요하다고 생각합니다.

귀하의 코드는 h5py에 파이썬 인터페이스를 사용하고 있으며, cythonizing은이를 알지 않습니다.

cython 코드는 저수준 작업, 특히 배열 작업으로 표현할 수없는 반복 작업에 가장 적합합니다. 먼저 numpy 예제를 사용하여 연구하고 실험하십시오. 수영장 끝에서 cython으로 뛰어 들고 있습니다.

파이썬과 numpy로 코드를 향상 시키려고 했습니까? 언뜻 보면 많은 중복 전화 번호 h5py이 나타납니다. 그것은 2에 의해 얻을 수있는 경우

====================

귀하의 radial 계산이 h5py 색인 6 번 액세스 어쩌면 당신은 그것을 썼다 방법이 cython numpy보다 빨리 다음 계산을 preform 것이라고 희망?

data = grp['HaloCatalog'] 
progen = data[progen_haloid-1, 6:9] 
host = data[host_id-1, 6:9] 
radial = np.sqrt((progren-host)**2).sum(axis=1)) 

data[progen_haloid-1,:]data[host_id-1,:] 모든로드되지? data도 모두? h5py이 파일의 배열과 직접 작업하지 않을 때와 배열이 numpy 일 때 검토해야합니다. 어쨌든, 메모리에있는 배열의 수학은 파일 읽기보다 훨씬 빠릅니다.

+0

감사합니다. 이전에 Numpy를 실험 해 보았습니다.하지만 그 기술로 Input 호출을 줄이는 것을 생각하지 않았습니다. 그러나 조금 느리다. 아마도 MPI 형식을 사용하여 작업을 분리하는 것이 가장 좋은 방법 일까? –

관련 문제