-
-
Notifications
You must be signed in to change notification settings - Fork 516
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add gappy as a standard package and use for sage's libgap interface #31297
Comments
This comment has been minimized.
This comment has been minimized.
New commits:
|
This comment has been minimized.
This comment has been minimized.
Branch: u/embray/gappy |
Author: Erik Bray |
Commit: |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Branch pushed to git repo; I updated commit sha1. New commits:
|
Replying to @embray:
See #29865 for this |
Branch pushed to git repo; I updated commit sha1. New commits:
|
This comment has been minimized.
This comment has been minimized.
comment:11
Travis, I'm curious about your take on this, especially on the impact to permutation groups, since this partly reverts #25609, which I see you worked on. AFAICT this makes some minor performance improvements in construction of permutation groups from Sage -> GAP, but might be a little slower for going from GAP -> Sage. |
This comment has been minimized.
This comment has been minimized.
Work Issues: release gappy 0.1.0 final and update spkg version before merging |
comment:14
Big +1 on this work (but I know too little about GAP to review) |
This comment has been minimized.
This comment has been minimized.
Branch pushed to git repo; I updated commit sha1. New commits:
|
comment:16
A quick remark on |
comment:17
I would like to bring the attention to cypari2 that played the role of gappy at the time the PARI/GP interface in Sage became an independent Cython module. In particular, if any design decision has to be made, it would be weird if they would be different for both interfaces. First of all, two things that seem different from the rough description of the ticket
There was no need for coercion because the most basic possible happen : in any mixture, everything is converted to a cypari2 Gen object. Here with integers
Here with matrices
I do not see the difference here with the GAP interface. In what sort of construction the interaction with categories/coercion has to be handled? I would like a more concrete description if possible. On a related note, cypari2 introduced the standardized name For the cypari2 -> Sage conversion, there is cdef class Gen:
def sage(self, locals=None):
r"""
Return the closest SageMath equivalent of the given PARI object.
INPUT:
- ``locals`` -- optional dictionary used in fallback cases that
involve ``sage_eval``
See :func:`~sage.libs.pari.convert_sage.gen_to_sage` for more information.
"""
from sage.libs.pari.convert_sage import gen_to_sage
return gen_to_sage(self, locals) |
Branch pushed to git repo; I updated commit sha1. New commits:
|
comment:32
Replying to @embray:
Just a quick note that the compile-time dependency of |
comment:33
Replying to @mkoeppe:
Good point. The remark applies equally to gappy and cypari2 (and possibly other libraries). In the same vein that Erik proposed in [comment:26] we could introduce a way to register conversions to Sage so that On the other hand, |
comment:34
Replying to @videlec:
Beyond conversions, many methods of
|
comment:35
These are just Python methods, not Crucial for the modularization is really just that the compiled Cython module no longer has such compile-time dependencies. |
comment:36
Replying to @mkoeppe:
Not really. |
comment:37
Thanks, you are right, of course. |
comment:38
On the other hand |
comment:39
Replying to @mkoeppe:
The problem with that is it is relatively slow IIRC. It might be better to have a Python subclass of |
comment:40
Replying to @mkoeppe:
I wonder if a minimal Integer base type wouldn't also be helpful here. Again all we need are base classes that have the same struct layout, and maybe a minimum of methods defined. |
comment:41
Replying to @videlec:
No, but a plain Python subclass of it is. |
comment:42
Another important example that doesn't work without coercion support which did before is evaluation of polynomials on GAP objects:
This doesn't work with PARI gens either unless you convert the polynomial to PARI explicitly first. |
comment:43
TIL: The coercion model does in fact already support a Adding this to
I wonder why pari_gen doesn't support this too. |
comment:44
Hrm, the problem with the above example though is that with |
Branch pushed to git repo; I updated commit sha1. New commits:
|
Branch pushed to git repo; I updated commit sha1. New commits:
|
This comment has been minimized.
This comment has been minimized.
Reviewer: Dima Pasechnik |
comment:49
let's do this the other way: #31404 |
Update: The successor to this ticket is #31404 which offers a different approach by using gappy directly in Sage rather than providing Sage-specific wrappers. I think it is overall a better approach for now.
Package tarball: see
checksums.ini
; use./configure --enable-download-from-upstream-url
to test.gappy is a new !Python/Cython package providing a Python interface to GAP using its public "libgap" API (to the extent possible).
It is the result of extracting Sage's
sage.libs.gap
package into a standalone package without a dependency on Sage, so it still bears some of the legacy of that package (which will continue to be cleaned up and improved on).One particular improvement is the help system for GAP functions--as before it is possible to extract documentation (when it exists) from the GAP docs, but this is faster now (previously the pexpect interface was still required) and can usually extract only the documentation for the queried function (previously it would also append the entire rest of the documentation chapter). It may also introduce some minor performance improvements in some areas, but it will be interesting to test this with some non-trivial examples.
This ticket is to attempt to convert
sage.libs.gap
to a wrapper around gappy (rather than replace it entirely). The main reason a wrapper is still needed, is in order to participate in Sage's coercion model.The GAP interpreter wrapper class
sage.libs.gap.libgap.Gap
is aParent
, and its elements are instances ofGapElement
and subclasses thereof which are subclasses ofElement
.This presents a challenge which makes wrapping gappy less straightforward than one would hope: Because the classes
gappy.Gap
andgappy.GapObj
(its equivalent ofGapElement
) are cdef classes, as well asParent
andElement
, it is not possible to use multiple inheritance likebecause their base structs are incompatible. The current workaround to this is that
GapElement
is a wrapper for aGapObj
(which in turn wraps C-level GAPObj
pointers). This creates a bit of unfortunate overhead, albeit not much; by usingcdef
andcpdef
methods, Cython can make the call to wrapped objects reasonably fast in many cases.TODO
Rework the
sage.libs.gap.assigned_names
andsage.libs.gap.all_documented_functions
modules.Fix more uses within sage of the deprecated
Gap.function_factory
method.Fix more tests; all test are passing in
sage.libs.gap
as well as all insage.groups.perm_gps
, but some tests elsewhere are failing.There are miscellaneous other functions in
sage.libs.gap
that can probably be deprecated or removed.Food for thought...
There are some other possible workarounds to this issue I would like to explore in the future.
The first is to change how gappy works: Rather than
Gap
andGapObj
beingcdef
classes, they could be pure-Python wrappers around somecdef
classes. This would again create some overhead, but hopefully not too much. Then they can participate in multiple inheritance with Sage'sParent
andElement
classes.The other two, which would be much more disruptive, but also possibly useful for other packages that would like to integrate with Sage without explicitly depending on it, and have been discussed before:
Create a relatively Sage "base" package with little to no mathematical functionality but that provides base classes for some of Sage's structural classes such as
SageObject
,Parent
, andElement
(maybe alsoCategoryObject
?). These base classes need not replicate the full functionality found in Sage, but just enough to provide some bootstrapping. If the package is relatively small and easily pip-installable, packages like gappy can use it as a dependency without requiring all of Sage. See Modularization of sagelib: Break out separate packages sagemath-objects, sagemath-categories #29865 for an in-progress viable prototype of this.A similar but subtly different option is to make classes like
SageObject
,Parent
, andElement
into Abstract Base Classes. Classes in other packages can then be registered as psuedo-subclasses of these ABCs without directly subclassing them, so long as they implement the necessary interfaces. This option is appealing to me since it means classes from other packages can more easily interface with Sage without requiring any additional dependencies. However, it is potentially more disruptive: There isn't a way to ensure that classes which register to an ABC to provide the same C-level interface (C methods and attributes). So Cython-level code that types variables asParent
orElement
won't work here, and would have to provide a separate (typically slower) code path for handle ABC pseudo-subclasses. Fortunately there is not a ton of code like this in Sage, but there is some, especially in code related to the coercion model, unsurprisingly.CC: @tscrim @dimpase @videlec
Component: interfaces
Keywords: gap libgap gappy
Work Issues: release gappy 0.1.0 final and update spkg version before merging
Author: Erik Bray
Branch/Commit: u/embray/gappy @
82e7e56
Reviewer: Dima Pasechnik
Issue created by migration from https://trac.sagemath.org/ticket/31297
The text was updated successfully, but these errors were encountered: