Skip to content

Conversation

pv
Copy link
Contributor

@pv pv commented Aug 4, 2019

It's possible to install the Sage system as a normal Python package, as
e.g. in Fedora/Debian. In this case, presence of sage.all is not an
indicator whether the user is running Sage, and checking for 'SAGE_ROOT'
is more reliable.

There are some behavior differences in mpmath with the Sage backend,
(e.g. mpmath.ker(0, 0) is 0 on sage but inf on gmpy), but a larger reason
for this change could be that the Sage backend probably makes sense mostly
when using Sage.

It's possible to install the Sage system as a normal Python package, as
e.g. in Fedora/Debian. In this case, presence of `sage.all` is not an
indicator whether the user is running Sage, and checking for 'SAGE_ROOT'
is more reliable.
@fredrik-johansson
Copy link
Collaborator

Seems OK.

The mpmath.ker(0, 0) discrepancy would be worth looking into, because results are meant to be identical.

@fredrik-johansson fredrik-johansson merged commit f115ce4 into mpmath:master Sep 5, 2019
@kiwifb
Copy link

kiwifb commented Mar 18, 2021

That was fairly silly as reasoning. System sage like sage-on-gentoo use system mpmath in their system sage. This change breaks the use of mpmath in a system install of sage. I'll admit that automated back end choice is a bit of an issue. But this change leads to this kind of stuff in sage-on-gentoo

fbissey@moonloop ~ $ sage -t --long --random-seed=0 /usr/lib/python3.9/site-packages/sage/calculus/calculus.py 
too many failed tests, not using stored timings
Running doctests with ID 2021-03-18-13-14-48-fb25a05d.
Using --optional=dochtml,memlimit,pip,sage
Doctesting 1 file.
sage -t --long --random-seed=0 /usr/lib/python3.9/site-packages/sage/calculus/calculus.py
**********************************************************************
File "/usr/lib/python3.9/site-packages/sage/calculus/calculus.py", line 372, in sage.calculus.calculus
Failed example:
    [f[0].n() for f in _.coefficients()]  # numerical coefficients to make comparison easier; Maple 12 gives same answer
Exception raised:
    Traceback (most recent call last):
      File "sage/symbolic/expression.pyx", line 6186, in sage.symbolic.expression.Expression.numerical_approx (/dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_9/build/cythonized/sage/symbolic/expression.cpp:37043)
        x = x._convert(kwds)
      File "sage/symbolic/expression.pyx", line 1495, in sage.symbolic.expression.Expression._convert (/dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_9/build/cythonized/sage/symbolic/expression.cpp:10451)
        cdef GEx res = self._gobj.evalf(0, kwds)
      File "sage/libs/pynac/pynac.pyx", line 2139, in sage.libs.pynac.pynac.py_psi2 (/dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_9/build/cythonized/sage/libs/pynac/pynac.cpp:25306)
        return mpmath_utils.call(mpmath.psi, n, x, prec=prec)
      File "sage/libs/mpmath/utils.pyx", line 439, in sage.libs.mpmath.utils.call (/dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_9/build/cythonized/sage/libs/mpmath/utils.c:7129)
        y = mpmath_to_sage(y, prec)
      File "sage/libs/mpmath/utils.pyx", line 272, in sage.libs.mpmath.utils.mpmath_to_sage (/dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_9/build/cythonized/sage/libs/mpmath/utils.c:5518)
        mpfr_from_mpfval(y.value, x._mpf_)
      File "sage/libs/mpmath/utils.pyx", line 167, in sage.libs.mpmath.utils.mpfr_from_mpfval (/dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_9/build/cythonized/sage/libs/mpmath/utils.c:4702)
        sign, man, exp, bc = x
    TypeError: Cannot convert mpz to sage.rings.integer.Integer

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "/usr/lib/python3.9/site-packages/sage/doctest/forker.py", line 714, in _run
        self.compile_and_execute(example, compiler, test.globs)
      File "/usr/lib/python3.9/site-packages/sage/doctest/forker.py", line 1133, in compile_and_execute
        exec(compiled, globs)
      File "<doctest sage.calculus.calculus[101]>", line 1, in <module>
        [f[Integer(0)].n() for f in _.coefficients()]  # numerical coefficients to make comparison easier; Maple 12 gives same answer
      File "<doctest sage.calculus.calculus[101]>", line 1, in <listcomp>
        [f[Integer(0)].n() for f in _.coefficients()]  # numerical coefficients to make comparison easier; Maple 12 gives same answer
      File "sage/structure/element.pyx", line 885, in sage.structure.element.Element.n (/dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_9/build/cythonized/sage/structure/element.c:8385)
        return self.numerical_approx(prec, digits, algorithm)
      File "sage/symbolic/expression.pyx", line 6190, in sage.symbolic.expression.Expression.numerical_approx (/dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_9/build/cythonized/sage/symbolic/expression.cpp:37116)
        x = x._convert(kwds)
      File "sage/symbolic/expression.pyx", line 1495, in sage.symbolic.expression.Expression._convert (/dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_9/build/cythonized/sage/symbolic/expression.cpp:10451)
        cdef GEx res = self._gobj.evalf(0, kwds)
      File "sage/libs/pynac/pynac.pyx", line 2139, in sage.libs.pynac.pynac.py_psi2 (/dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_9/build/cythonized/sage/libs/pynac/pynac.cpp:25306)
        return mpmath_utils.call(mpmath.psi, n, x, prec=prec)
      File "sage/libs/mpmath/utils.pyx", line 439, in sage.libs.mpmath.utils.call (/dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_9/build/cythonized/sage/libs/mpmath/utils.c:7129)
        y = mpmath_to_sage(y, prec)
      File "sage/libs/mpmath/utils.pyx", line 272, in sage.libs.mpmath.utils.mpmath_to_sage (/dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_9/build/cythonized/sage/libs/mpmath/utils.c:5518)
        mpfr_from_mpfval(y.value, x._mpf_)
      File "sage/libs/mpmath/utils.pyx", line 167, in sage.libs.mpmath.utils.mpfr_from_mpfval (/dev/shm/portage/sci-mathematics/sage-9999/work/sage-9999/src-python3_9/build/cythonized/sage/libs/mpmath/utils.c:4702)
        sign, man, exp, bc = x
    TypeError: Cannot convert mpz to sage.rings.integer.Integer
**********************************************************************
1 item had failures:
   1 of 113 in sage.calculus.calculus
    [429 tests, 1 failure, 9.93 s]
----------------------------------------------------------------------
sage -t --long --random-seed=0 /usr/lib/python3.9/site-packages/sage/calculus/calculus.py  # 1 doctest failed
----------------------------------------------------------------------
Total time for all tests: 10.0 seconds
    cpu time: 10.6 seconds
    cumulative wall time: 9.9 seconds
fbissey@moonloop ~ $ SAGE_ROOT=1 sage -t --long --random-seed=0 /usr/lib/python3.9/site-packages/sage/calculus/calculus.py 
too many failed tests, not using stored timings
Running doctests with ID 2021-03-18-13-18-15-7c4bcb36.
Using --optional=dochtml,memlimit,pip,sage
Doctesting 1 file.
sage -t --long --random-seed=0 /usr/lib/python3.9/site-packages/sage/calculus/calculus.py
    [429 tests, 9.94 s]
----------------------------------------------------------------------
All tests passed!
----------------------------------------------------------------------
Total time for all tests: 10.0 seconds
    cpu time: 10.7 seconds
    cumulative wall time: 9.9 seconds

@oscarbenjamin
Copy link

Is there a related upstream issue as reference?

@kiwifb
Copy link

kiwifb commented Mar 18, 2021

If by upstream you mean sagemath, then no. We have just stumbled across this in sage-on-gentoo yesterday cschwan/sage-on-gentoo#628. I think this change assumed that a system sage like the one shipped with fedora or debian is bringing a private copy of mpmath. This is not the case for Gentoo and I assume arch.

@kiwifb
Copy link

kiwifb commented Mar 18, 2021

It looks like I can get away with it by setting MPMATH_SAGE=1 rather then SAGE_ROOT. May be we should have some change in sage upstream to make sure MPMATH_SAGE is set when calling mpmath. While I want to make sure you are aware that the SAGE_ROOT assumption was simplistic, something probably needs to be done inside sage as well.

@asmeurer
Copy link
Contributor

I agree with this change in principle. Sage itself should be responsible for "enabling" sage mode when it imports mpmath (only I don't know if an environment variable is the right way to go about that, which is why I say "in principle"). It is also possible to install Sage using conda-forge, and the exact same problem exists there. If you install Sage into a conda environment, a ton of SymPy tests start failing, because they do not work properly when mpmath uses the Sage backend (I haven't investigated these tests so I can't say if they are legitimate bugs or just small numerical differences). Here is the upstream issue https://trac.sagemath.org/ticket/25445 (see also sympy/sympy#14703).

Ideally, mpmath could use both backends at the same time, by switching out a context at runtime, so that Sage can use its Sage backend and SymPy can use the normal backend(s) in the same process. I don't know if this use case is important enough to add this complexity to mpmath, however.

You could argue this is sort of a Sage issue. There are a lot of bad things that can happen if you import Sage in a normal Python environment (e.g., IIRC unless this has changed, it also hooks the interpreter in some ways that makes exceptions print differently). Installing Sage into the same Python environment you plan to use for non-Sage things is a bad idea. If gentoo is doing that, it should reconsider. But the fact that mpmath just imports sage when it can find it exacerbates this problem. That means that, prior to this fix, simply doing conda install sage will break SymPy in that environment.

@kiwifb
Copy link

kiwifb commented Mar 18, 2021

I acknowledge that the situation sympy/mpmath/sage has been ongoing for some time. sage in sage-on-gentoo has been a normal python package that you can import from python since about sage-5.0. Recent sympy have not exhibited problems in sage-on-gentoo but for a while I had some environment variable specifically set for it.

In effect this is the first time in a couple of years since I had an issue of this kind. But the fact that once sage is installed you have to explicitly tell mpmath not to use it is something I understand you find less than ideal. I am currently trying a simple fix in upstream sage but I don't know if it will catch enough things.

@asmeurer
Copy link
Contributor

I don't know if this still the case, but Sage used to have pretty stringent pinning of some dependencies, which was another reason to prefer using a separate environment for conda. @isuruf would need to comment on whether that is still the case. Also as I mentioned, I noticed back in 2018 that Sage was hooking the interpreter in some ways when it was imported. I don't know if this is still relevant. I don't follow Sage development at all, though, so it is very possible that these are no longer significant issues. It definitely was the case then that Sage was not at all designed to be installed as a library alongside a normal Python environment. That's obviously an even bigger issue when something like mpmath eagerly imports sage if it sees that it is installed. Importing Sage also is slow. import mpmath takes over a second with MPMATH_SAGE=1 and about 0.1 seconds without.

@kiwifb
Copy link

kiwifb commented Mar 18, 2021

Still does need some stringent pinning of some dependencies (singular, pari...). This is unfortunate but also the result of the fact that most of those packages have APIs that are not very stable. Separate environment and other containment strategies are obviously a good way to have a handle on those issues from the user perspective, not so much from the regular packager perspective.

@asmeurer
Copy link
Contributor

For conda environments are trivial, so it isn't a big deal. The main issue really is messaging to users that Sage is very much a package that you want to have in a separate environment, rather than your "main" environment. I understand that no all package managers have straightforward environments like conda does, including most Linux system package managers, so it's a harder problem there.

@kiwifb
Copy link

kiwifb commented Mar 18, 2021

Nod in agreement. The ticket you opened years ago is getting renewed interest https://trac.sagemath.org/ticket/25445. I think the fact sage is not working properly if you are not using the sage backend is a sage bug. It shouldn't matter, beside possible numerical noise, and the fact it does means the internal of mpmath are abused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants