On 11/30/2010 10:04 PM, Vitja Makarov wrote:
> 2010/11/30 Dag Sverre Seljebotn<[email protected]>:
>    
>> On 11/30/2010 08:26 PM, Robert Bradshaw wrote:
>>      
>>> On Tue, Nov 30, 2010 at 10:52 AM, Dag Sverre Seljebotn
>>> <[email protected]>    wrote:
>>>
>>>        
>>>> On 11/30/2010 07:28 PM, Robert Bradshaw wrote:
>>>>
>>>>          
>>>>> On Tue, Nov 30, 2010 at 2:12 AM, Dag Sverre Seljebotn
>>>>> <[email protected]>      wrote:
>>>>>
>>>>>
>>>>>            
>>>>>> On 11/30/2010 06:35 AM, Robert Bradshaw wrote:
>>>>>>
>>>>>>
>>>>>>              
>>>>>>> On Mon, Nov 29, 2010 at 9:20 PM, Vitja Makarov<[email protected]> 
>>>>>>>        wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>                
>>>>>>>> 2010/11/30 Robert Bradshaw<[email protected]>:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>                  
>>>>>>>>> On Mon, Nov 29, 2010 at 12:27 PM, Greg Ewing
>>>>>>>>> <[email protected]>        wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>                    
>>>>>>>>>> Stefan Behnel wrote:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>                      
>>>>>>>>>>> * it makes the inner C function directly callable, thus making it 
>>>>>>>>>>> easier to
>>>>>>>>>>> implement things like cpdef functions and generators on top.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>                        
>>>>>>>>>> If you mention the name of such a function without calling it,
>>>>>>>>>> does it refer to the C function or the Python function?
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>                      
>>>>>>>>> That would depend on the context in which it's being used.
>>>>>>>>> Essentially, the as_variable attribute would be set, allowing it to
>>>>>>>>> coerce to a Python object if need be.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>                    
>>>>>>>> I see problem with closures here where should scope object be created
>>>>>>>> in C function or in wrapper?
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>                  
>>>>>>> The only handle you can get of a closure object is a Python one.
>>>>>>> (Well, eventually we want to have cdef closures, but we're not there
>>>>>>> yet, and wouldn't be compatible with cdef functions--we'd probably
>>>>>>> expose them as structs with a state and function pointer attributes.)
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>                
>>>>>> Just for reference: Carl recently made me aware that ctypes contain some
>>>>>> code to proxy Python functions to C function pointers. And apparently it
>>>>>> contains a small compiler that creates new CPU code on demand for this.
>>>>>> I'm not sure how well that would be exposed for our purposes, if it has
>>>>>> a C API or not. (I haven't really looked at this myself.)
>>>>>>
>>>>>> Being able to create a closure in Cython and pass it as an ordinary C
>>>>>> function callback, without having to manage the context manually, would
>>>>>> be a really cool feature! And with such a mini-compiler it is possible.
>>>>>>
>>>>>> (Same idea applies to a concept of "pointer to bound cdef method")
>>>>>>
>>>>>>
>>>>>>              
>>>>> Wow, that's a pretty interesting idea. Does this limit the
>>>>> applicability to certain architectures? Of course even if the context
>>>>> needs to be handled separately, we could make it easier than it is
>>>>> now.
>>>>>
>>>>>
>>>>>            
>>>> Spending five more minutes on this, ctypes uses the libffi library
>>>> (which is simply bundled with Python, although I haven't probed into
>>>> whether this means it will always be available in a form we can link
>>>> with). It appears to be very user-friendly, and has specific routines
>>>> for creating C closures.
>>>>
>>>> Google it to see platform availability. Apparently closures are not
>>>> available on every platform, but a grep through the source for
>>>> FFI_CLOSURES seem to indicated that the "moxie", "m32r" and "m68k"
>>>> platforms are the only ones without closure support. I can live with
>>>> that :-) Looks to me like libffi lies at the core of a lot of FFI out
>>>> there so that support is rather good.
>>>>
>>>>          
>>> Very cool. I'm completely fine with relying on this library (bundled
>>> with Python) for our use. The only downside is that documentation
>>> seems a bit sparse, but I'm sure we can figure it out.
>>>
>>>        
>> There's an "info" file in the doc subdir in the tarball, not sure if you
>> saw that. It has some examples of use at least.
>>
>> Dag Sverre
>>
>>
>>      
>>>        
>>>> At any rate, it seems tempting to just make Cython cdef closures simply
>>>> be libffi closures.
>>>>
>>>>          
>>> Yep. This would give a nice way to get bound cdef methods as well
>>> (though I could see value in being able to go back to the unbound
>>> version, not sure how easy that would be).
>>>
>>> - Robert
>>> _______________________________________________
>>> Cython-dev mailing list
>>> [email protected]
>>> http://codespeak.net/mailman/listinfo/cython-dev
>>>
>>>        
> I don't like the idea to add one more external dependency. But if that
> really helps its okay.
>    

If we can manage to link with the libffi shipped with CPython it's not 
really adding a dependency... Also, this is for a feature that's not in 
Cython today, so it's not like we're breaking anything anyway.

> Also libffi is not supported on blackfin architecture :(
>    

I'm not familiar with that architecture. Do you know if CPython is 
supported on it? (If so I assume with disabled ctypes?)

> Here is simple example from libffi documentation:
>       #include<stdio.h>
>       #include<ffi.h>
>
>       /* Acts like puts with the file given at time of enclosure. */
>       void puts_binding(ffi_cif *cif, unsigned int *ret, void* args[],
>                         FILE *stream)
>       {
>         *ret = fputs(*(char **)args[0], stream);
>       }
>
>       int main()
>       {
>         ffi_cif cif;
>         ffi_type *args[1];
>         ffi_closure *closure;
>
>         int (*bound_puts)(char *);
>         int rc;
>
>         /* Allocate closure and bound_puts */
>         closure = ffi_closure_alloc(sizeof(ffi_closure),&bound_puts);
>
>         if (closure)
>           {
>             /* Initialize the argument info vectors */
>             args[0] =&ffi_type_pointer;
>
>             /* Initialize the cif */
>             if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
>                              &ffi_type_uint, args) == FFI_OK)
>               {
>                 /* Initialize the closure, setting stream to stdout */
>                 if (ffi_prep_closure_loc(closure,&cif, puts_binding,
>                                          stdout, bound_puts) == FFI_OK)
>                   {
>                     rc = bound_puts("Hello World!");
>                     /* rc now holds the result of the call to fputs */
>                   }
>               }
>           }
>
>         /* Deallocate both closure, and bound_puts */
>         ffi_closure_free(closure);
>
>         return 0;
>       }
>
> I don't actually understand how do you want to use libffi in Cython.
> Can you provide some usecase, please?
>    

Sure. I want to do this:

cdef extern from "mylib.h":
     cdef double integrate(double from, double to_, double 
(*func)(double x)) # Not sure, I can never get this right

cdef extern from "math.h":
     cdef double sin(double)

def integrate_scaled_sin(from, to_, double a):
     cdef double scaled_sin(double x):
         return sin(a * x) # all C
     return integrate(from, to_, &scaled_sin)

AND, since mylib.h is written by your standard numerical scientist, it's 
not a stretch to assume that it doesn't allow for a context pointer, 
like it should have.

I don't really understand the example fully, but it looks like you'd

a) Have some normal static "pyx_scaled_sin" function that would fill the 
role of puts_binding above; reading "a" from its argument list

b) Inside the implementation of integrate_scaled_sin, one would use 
ffi_closure_alloc and ffi_prep_closure_loc to bind the local variables 
and get a simple pointer "double (*func)(double)".

c) This pointer can be passed directly to the "integrate" function 
above. When called, the libffi magic kicks in and calls pyx_scaled_sin 
with the correct (enclosured) arguments.

Dag Sverre

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

Reply via email to