On Jul 5, 2008, at 11:50 AM, Dag Sverre Seljebotn wrote:
> Robert Bradshaw wrote:
>> If I understand correctly, the issue here is how to map cython/c
>> types to the "format" string of the buffer. There are three things to
>> match:
>>
>> Numeric type (int/float)--this can be detected at compile time by
>> (<type>1)/(<type>2) == 0 vs the buffer format string
>> Signed--this can be detected at compile time by (<type>-1) < 0 vs the
>> buffer format string
>> Size--this can be detected at compile time by sizeof() vs the
>> "itemsize" field of the buffer, or calcsize from the struct module if
>> you need.
>
> Very nice!
>
> Or simply sizof(type) vs sizeof(int).
>
>> All other types are required to match exactly (or something like
>> that, some thought would have to be put into how to handle objects).
>> For hybrid types I think it would be enough to just look at the total
>> size after comparing the structs for (int/float/other and signed/
>> unsigned). Then you could use numpy.uint and numpy.unit32, etc.
>
>
> OK, writeup for clarity in the discussion, this is what needs to
> happen:
>
> - A format string is recieved run-time when acquiring a buffer
> - We have a compile-time assumed type for the buffer
> - They need to be compared for sanity-checking
Exactly.
> And this is how I see it happen (which is quite different from what I
> thought a day ago):
>
> - For each type used in a buffer, Cython will output a string-
> validating
> inline function for that type.
>
> - For structs (and other complicated things) this essentially boils
> down
> to checking if a string corresponds to a known structure and is
> relatively straightforward if potentially messy/wordy. (These will not
> even be supported until working buffers for simple types hits
> cython-devel IMO, iterative programming and all that...)
>
> - When the exact C type is used directly, something like this may be
> used (if I bother to treat it specially):
>
> int Pyx_typestring_matches_unsigned_int(char* s) {
> /* skipping the one-char check for now*/
> return *s == 'U';
> }
>
> - When a typedef-ed type is output, something like this is used:
>
> int Pyx_typestring_matches_npy_uint8(char* s) {
>
> /* skipping the one-char check for now*/
>
> switch (*s) {
> case 'i':
> return (((npy_uint8)1)/(npy_uint8)2) == 0) &&
> ((npy_uint8)-1 < 0) && sizeof(npy_uint8) == sizeof(int);
> ...
> }
> }
>
> This should translate to a switch statement where every branch but one
> will return false, and I think it is reasonable to hope the compiler
> will make it as efficient as the former case.
Yep, looks good to me. The compiler will have no trouble evaluating
these constant expressions and pruning the tree. In retrospect, I
think the ((type)1)/((type)2) == 0 trick is probably overkill, the
person who declares the type should ctypedef it as an int or float
correctly, we don't need to be double-guessing that.
> Thanks! :-)
Any time :-)
- Robert
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev