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

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.

Thanks! :-)

-- 
Dag Sverre
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to