Re: gap C library Python interface

9 views
Skip to first unread message

William Stein

unread,
Jun 25, 2009, 4:57:59 PM6/25/09
to David Joyner, Steve Linton, sagedays16, Ryan Dingman, rlm...@math.washington.edu
On Thu, Jun 25, 2009 at 9:02 PM, David Joyner<wdjo...@gmail.com> wrote:
> On Thu, Jun 25, 2009 at 2:26 PM, William Stein<wst...@gmail.com> wrote:
>> Hi Steve and David,
>>
>> FYI, I've been writing a Python --> GAP   *C library* interface the
>> last 3 days at Sage days.
>> It is about 1000 times faster than the pexpect interface, and will
>
>
> Wow. GAP is not really a C library so you must have created an
> interface with the kernel effectively creating a library? Pretty amazing.

That's exactly right. It's pretty exciting to me. E.g.,

teragon:src wstein$ sage
----------------------------------------------------------------------
| Sage Version 4.0.2, Release Date: 2009-06-18 |
| Type notebook() for the GUI, and license() for information. |
----------------------------------------------------------------------
sage: a = sage.libs.gap.gap.GapObj('394')
sage: type(a)
<type 'sage.libs.gap.gap.GapObj'>
sage: b = sage.libs.gap.gap.GapObj('10394')
sage: timeit('a*b')
625 loops, best of 3: 381 ns per loop

Compare to pexpect (which is 1414 times slower for this):

sage: a = gap('394'); b = gap('10394')
sage: timeit('a*b')
625 loops, best of 3: 539 µs per loop

sage: 539/.381
1414.69816272966

sage: G = sage.libs.gap.gap.GapObj(SL(2,3))
sage: Order = sage.libs.gap.gap.GapObj("Order"); Order
Operation "Order"
sage: Order(G)
24
sage: a*b
4095236

> Sounds amazing. I'd be very interested to know how it works.

I read the GAP kernel source. It wasn't so hard, because the GAP
kernel source code is very easy to read (compared to say PARI or
Singular!). Then I just implemented a Cython version of the
Read/Eval/Print loop, which returns a GAP Obj. I have a Cython class
that wraps an Obj.
The code for arithmetic looks like this:

def __mul__(GapObj self, GapObj right):
cdef GapObj r = PY_NEW(GapObj)
r.value = PROD(self.value, right.value)
return r

Here PROD is a macro in the GAP kernel. Note that there is no error
checking above yet, but even that is easy by checking the NrError
variable in the GAP kernel.

To get any of this going, I first had to build GAP with the -fPIC
flag, delete the main function, then combine everything else together
into an archive using "ar".

There is some code here: http://trac.sagemath.org/sage_trac/ticket/6391
but I don't recommend trying this out just yet (!). It's far from done.

The main motivation was there was starting to be a lot of serious
discussion among some Sage developers about rewriting substantial
parts of GAP in Cython/Python. First, massively improving the Sage
<--> GAP link and improving how we use GAP (and maybe even GAP itself)
might be a better use of resources.

I expected this to be a lot harder than it was, and the reason it
wasn't ridiculously hard is because the GAP kernel code is very easy
to read, well documented, and designed in a straightforward manner in
C.

-- William


>
>> dramatically improve how
>> Sage uses GAP...
>>
>> :-)
>>
>> william
>>
>> --
>> William Stein
>> Associate Professor of Mathematics
>> University of Washington
>> http://wstein.org
>>
>

--
William Stein
Associate Professor of Mathematics
University of Washington
http://wstein.org

Reply all
Reply to author
Forward
0 new messages