Skip to content
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

Better coercion to ZZ for libGAP integers, modular integers #37580

Merged

Conversation

kedlaya
Copy link
Contributor

@kedlaya kedlaya commented Mar 10, 2024

This PR implements some more sensible conversions for libGAP integers and modular integers.

For integers, we fix a TODO to convert long libGAP integers by directly accessing their underlying GMP integers. The current implementation instead uses a decimal string representation as an intermediate step.

For modular integers, we implement a lift method; this allows the .sage method to use a more direct coercion into the appropriate ring.

@kedlaya
Copy link
Contributor Author

kedlaya commented Mar 10, 2024

Is this duplicating changes in gappy by any chance?

@dimpase
Copy link
Member

dimpase commented Mar 10, 2024

AFAIK, gappy didn't go there, it's an unfinished (sadly) attempt to spin the Cython interface to (lib)gap into a separate Python package.

@dimpase
Copy link
Member

dimpase commented Mar 10, 2024

Oops, no, my memory served me wrong, this part indeed was fixed in gappy, more precisely, in gappy+reworked Sage inteface to gappy, see https://github.com/sagemath/sagetrac-mirror/tree/u/dimpase/gappy-without-wrappers (look at the diff of element.pyx and see the chunk with "waste" comment removed)

@tscrim
Copy link
Collaborator

tscrim commented Mar 16, 2024

However, shouldn't we just fix this within our own code (independently of gappy)?

@dimpase
Copy link
Member

dimpase commented Mar 16, 2024

well, it would be nice, but this PR doesn't work - exactly at this place, it seems, see CI output
(nowadays you can just click on https://github.com/sagemath/sage/pull/37580/files and scroll down)

@kedlaya
Copy link
Contributor Author

kedlaya commented Mar 17, 2024

Oops, it looks like I pushed the wrong version of the code originally. This is now fixed and the checks seem to be passing now.

elif size < 0:
c_sign = -1
c_size = -size
else: # Something is wrong, fall back to string representation
Copy link
Member

@dimpase dimpase Mar 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need this else? As far as I understand from Int GAP_SizeInt(Obj obj) you get size==0, the only 3rd possible case, if self.value==0. In any event, there seem to be nothing "wrong" with getting 0 here.

@fingolfin - is this right?

Note that if I call GAP_SizeInt() on a non-integer, I'll get

Error, GAP_SizeInt: <obj> must be an integer (not a list (string))

As far as I see, GAP's Ints are created by (GAP_)MakeObjInt(limbs,size), with limbs an array of unsigned ints, and size being >0 for getting a positive Int, <0 for getting negatve Int, and 0 for getting 0.

As far as I understand, c_size should be 1 if size==0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact the else should never be triggered: if self.value == 0 then self.is_C_int() should return True, so we don't reach this if in the first place.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dimpase yes that's right (and documented like that).

Of course @kedlaya is also right -- but it seems odd to fall back to string representation then: if you are at this point, something major is wrong...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fingolfin - oops, I should have looked at GAP's src/integer.h

(or is there any other source for docs?)

r"""
TESTS::

sage: n = libgap.eval('One(ZmodnZ(123)) * 13')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also do this:

Suggested change
sage: n = libgap.eval('One(ZmodnZ(123)) * 13')
sage: n = libgap.eval('ZmodnZObj(13, 123))')

or, if libgap makes it easy to directly call GAP functions with small int arguments, then something like this:

Suggested change
sage: n = libgap.eval('One(ZmodnZ(123)) * 13')
sage: n = libgap.ZmodnZObj(13, 123)

@kedlaya
Copy link
Contributor Author

kedlaya commented Mar 18, 2024

Looking at this file some more, I see various GAP commands being surrounded by GAP_Enter() (or sometimes sig_GAP_Enter()) and GAP_Leave. Does anyone know when these are needed? Is it safe to omit them when executing commands that access GAP objects without creating or modifying them?

Copy link

github-actions bot commented Mar 27, 2024

Documentation preview for this PR (built with commit 2bcbfd6; changes) is ready! 🎉
This preview will update shortly after each push to this PR.

@vbraun
Copy link
Member

vbraun commented Jun 22, 2024

GAP_Enter is for marking the stack bottom. Gap's garbage collector will scan through the stack and look for pointers that look like gap memory bags to keep them alive (accepting possibly false positives). If the stack bottom is wrong then it might erroneously garbage collect gap memory bags.

Not all gap commands can cause garbage collection to run (roughly the C macros don't, but thats not a 100% reliable rule). If in doubt its better to add the GAP_Enter (which is super-fast, just writes one pointer) than to cause hard-to-debug bugs where an alive object can be erroneously garbage collected.

@kedlaya
Copy link
Contributor Author

kedlaya commented Jul 1, 2024

Fair enough, I added GAP_Enter and GAP_Leave calls to the key method.

@fchapoton fchapoton self-assigned this Jul 16, 2024
Copy link
Contributor

@fchapoton fchapoton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me

@vbraun vbraun merged commit 1a3d1d8 into sagemath:develop Jul 24, 2024
21 of 22 checks passed
@mkoeppe mkoeppe added this to the sage-10.5 milestone Jul 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants