http://wiki.cython.org/enhancements/numpy
    

One more comment about the constructor described on the page above.
It would be good if we could have the same syntax as the current
numpy.ndarray, and then simply call through to the underlying C
constructor.  We'd also need zeros, empty, ones_like and some other
select functions.  The goal is to remain as faithful as possible to
the original API, so that there is hardly a distinction between Python
and Cython.
  
This will be automatic from how Cython operates :-) And that is, I think, what makes all of this great. Objects are Python objects all the time and by default retain all Python implementation, and we only override this implementation when the behaviour is retained.

I'll walk through this code line by line:
cdef c_numpy.ndarray(c_numpy.float, 2) x
x = exp(4 + numpy.zeros([10, 10], dtype=numpy.float))
y = x + 3
print x[1, 3]
print y[3, 5]

#1: This is only a variable type declaration and constructs nothing.

#2: Operating on Python objects as normal (there is nothing "special" about numpy.zeros from the perspective of Cython, it returns a Python object like all other Python functions), and the resulting object is then assigned to the typed x variable; which is no different from assigning it to an untyped variable except that a run-time type-check assertion is inserted (is the Python object an ndarray object with the right dimensions and data type).

#3: (x + 3) will treat x as a Python object once again, so y will be an untyped variable referencing an ndarray like normal Python.

#4: This is where it gets interesting. Because x is typed so that Cython knows the C structure of the Python objects, it translates this directly to a lookup in the buffer, using stride information, so that it ends up as saying something like *(x->data + x->strides[0] * 1 + x->strides[1] * 3) directly in C (though hopefully we can in time cache strides lookups outside for loops etc, see the gcc discussion on the page).

#5: Here the data is instead accessed through the ndarray's Python __getitem__, which is much slower: A tuple is constructed, 3 and 5 put into the tuple, the tuple passed to ndarray.__getitem__ (or similar for extension types...) and so on.

Question: How does strides fit in this? I've been thinking that strides could merely fall back to the Python access method because it is somewhat of a high-level operation; is there any significant gains in skipping the Python access layer? (However this question is not important for the design and either approach will fit in, so it is not a big concern for me now.)

-- 
Dag Sverre
_______________________________________________
Numpy-discussion mailing list
Numpy-discussion@scipy.org
http://projects.scipy.org/mailman/listinfo/numpy-discussion

Reply via email to