2012-01-10 18 views
20

Tôi muốn có một đối tượng Cython "cdef" với thành viên NumPy và có thể sử dụng truy cập bộ đệm nhanh. Lý tưởng nhất, tôi sẽ làm một cái gì đó như:Khai báo bộ đệm Cython cho các thành viên đối tượng

import numpy as np 
cimport numpy as np 

cdef class Model: 
    cdef np.ndarray[np.int_t, ndim=1] A 

    def sum(self): 
    cdef int i, s=0, N=len(self.A) 
    for 0 <= i < N: 
     s += self.A[i] 
    return s 

    def __init__(self): 
    self.A = np.arange(1000) 

Thật không may, Cython không thể biên dịch điều này, với lỗi Buffer types only allowed as function local variables.

Cách giải quyết Tôi đang sử dụng là khai báo bộ đệm thuộc tính trên một biến địa phương mới, giao cho thành viên đối tượng:

cdef class Model: 
    cdef np.ndarray A 

    def sum(self): 
    cdef int i, s=0, N=len(self.A) 
    cdef np.ndarray[np.int_t, ndim=1] A = self.A 
    for 0 <= i < N: 
     s += A[i] 
    return s 

này trở nên thực sự khó chịu nếu bạn muốn có nhiều phương pháp truy cập vào cùng một dữ liệu cấu trúc - có vẻ như một trường hợp sử dụng khá phổ biến, phải không?

Có giải pháp nào tốt hơn không yêu cầu khai báo lại các loại bên trong mọi phương pháp không?

Trả lời

6

Giải pháp mà bạn hiện đang sử dụng là những gì tôi có xu hướng sử dụng, tức là tạo bản sao cục bộ trong hàm. Nó không thanh lịch, nhưng tôi không nghĩ rằng bạn có một hit hiệu suất rất lớn (hoặc ít nhất là trong trường hợp của tôi, tôi đang làm rất nhiều công việc trong phương pháp, do đó, nó không làm cho một sự khác biệt rõ rệt). Tôi cũng đã tạo một mảng C trong phương thức __cinit__ và sau đó điền nó với dữ liệu trong __init__ (hãy chắc chắn rằng bạn sử dụng __dealloc__ để dọn dẹp đúng cách). Bạn mất một số tính năng của mảng numpy, nhưng bạn vẫn có thể sử dụng nó như bạn sẽ là một mảng c.

Bạn cũng có thể kiểm tra các cuộc thảo luận trong email cũ này vào danh sách cython:

http://codespeak.net/pipermail/cython-dev/2009-April/005214.html

+2

cập nhật link http://www.mail-archive.com/[email protected]/msg05166.html – gg349

+0

Điều này có làm mất hiệu suất không? – machen

13

còn có tùy chọn để làm việc với bộ nhớ lát hoặc mảng cython http://docs.cython.org/src/userguide/memoryviews.html

import numpy as np 
cimport numpy as np 

    cdef class Model: 

    cdef int [:] A 

    def sum(self): 

     for 0 <= i < N: 
      s += self.A[i] 
     return s 

    def __init__(self): 
     self.A = np.arange(1000) 
+0

Khi bạn sử dụng phương pháp này, bạn có thể mất hiệu suất? Tôi hồ sơ này: stringsource: 368 (__ dealloc__) và stringsource: 341 (__ cinit__). Nhân tiện, điều này cũng được thảo luận trong https://stackoverflow.com/questions/21056696/when-profiling-cython-code-what-is-stringsource – machen

+0

Giải pháp thanh lịch về vấn đề yêu cầu này là gì? – machen

Các vấn đề liên quan