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

Optimize Psi2() #21388

Closed
embray opened this issue Sep 1, 2016 · 17 comments
Closed

Optimize Psi2() #21388

embray opened this issue Sep 1, 2016 · 17 comments

Comments

@embray
Copy link
Contributor

embray commented Sep 1, 2016

We greatly optimize the Psi2() function.

Before:

sage: from sage.schemes.elliptic_curves.isogeny_small_degree import Psi2
sage: timeit('Psi2.f(71)')
5 loops, best of 3: 9.36 s per loop

After:

sage: from sage.schemes.elliptic_curves.isogeny_small_degree import Psi2
sage: timeit('Psi2.f(71)')
5 loops, best of 3: 875 ms per loop

(note the use of Psi2.f() to bypass caching)


This also provides a workaround to a test that caused the Python interpreter to segfault on Windows. The specific call that caused the segfault is:

Psi2(71)

But in brief, the crash occurs because we have (in the original code) a large element of Univariate Quotient Polynomial Ring in v over Multivariate Polynomial Ring in x, u over Rational Field with modulus v^2 - u^4 + 10*u^3 + 3*u^2 - 4*u + 8. This is then being cast simply to a multivariate rational polynomial over x, u, v. Because there is no direct coercion between these types this involves eval()-ing the polynomial as a Python expression.

The problem is that this expression can become too large for the stack--specifically in Python's symbol visibility analysis, a step it performs just before compiling an expression to bytecode. The implementation of that recurses into binary expressions, leading to a stack overflow for such a large expression. This issue has come up once before in #16014 where it was worked around by a rewrite of the code. This particular test worked on Linux where the default stack size is 8MB, but it crashed on Windows where the typical stack is just 1MB.

The optimization gives smaller expressions to eval.

A more general fix to this problem would be nice though--I'm writing up some thoughts I have on it in a separate post.

Component: elliptic curves

Author: Erik Bray, Jeroen Demeyer

Branch/Commit: bdce5dc

Reviewer: Jeroen Demeyer, Erik Bray

Issue created by migration from https://trac.sagemath.org/ticket/21388

@embray embray added this to the sage-7.4 milestone Sep 1, 2016
@jdemeyer

This comment has been minimized.

@jdemeyer

This comment has been minimized.

@jdemeyer
Copy link

jdemeyer commented Sep 2, 2016

Changed branch from u/embray/psi2 to u/jdemeyer/psi2

@jdemeyer
Copy link

jdemeyer commented Sep 2, 2016

Changed commit from 9b22d75 to 10ff2ec

@jdemeyer
Copy link

jdemeyer commented Sep 2, 2016

comment:5

In fact, we don't need the variable x in the ring R at all...

Hang on...


New commits:

10ff2ecWorkaround to prevent this calculation to blow the stack

@embray
Copy link
Contributor Author

embray commented Sep 2, 2016

comment:6

Is the idea that you would just take the multiplication by x outside?

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 2, 2016

Changed commit from 10ff2ec to bdce5dc

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 2, 2016

Branch pushed to git repo; I updated commit sha1. New commits:

bdce5dcOptimize Psi2()

@jdemeyer

This comment has been minimized.

@jdemeyer
Copy link

jdemeyer commented Sep 2, 2016

Changed author from Erik Bray to Erik Bray, Jeroen Demeyer

@jdemeyer jdemeyer changed the title Make Psi2 function less likely to break the stack Optimize Psi2() Sep 2, 2016
@jdemeyer
Copy link

jdemeyer commented Sep 2, 2016

comment:9

This also happens to speed up the function by a factor of 10.

Please review...

@embray
Copy link
Contributor Author

embray commented Sep 2, 2016

comment:10

Some of this makes sense to me (I was already irked by the use of += []) but the rest is a little beyond my understanding of how Sage works (though I'd appreciate a brief explanation :)

That said it's no surprise to me that more could be done with this than what I did.

@jdemeyer
Copy link

jdemeyer commented Sep 2, 2016

comment:11

Replying to @embray:

Some of this makes sense to me (I was already irked by the use of += []) but the rest is a little beyond my understanding of how Sage works (though I'd appreciate a brief explanation :)

  1. Some general code cleanup and reformatting, in particular adding some spaces.

  2. To construct the rational number 1/x, I use QQ((1,x)) instead of 1/QQ(x).

  3. I remove raise ValueError("%s must be one of %s."%(l,hyperelliptic_primes)) since that exception is already raised by _hyperelliptic_isogeny_data.

  4. I rename y -> v to avoid confusion (the first v and the second v are really the same thing conceptually).

  5. I remove the variable x from the first R since it's never used. This is probably where the main speed-up comes from.

  6. I replace s = [1] by s = [K(1)] to ensure that all elements of s have K as parent.

  7. I replace your R((-1)**i*s[i]*x**(d-i)) by (-1)**i * x**(d-i) * R(s[i]). Since s[i] does not involve the variable x at all, I can indeed first convert s[i] to R and then multiply with x.

  8. I replace s[i] by s[i].lift() before conversion. This means "forgetting" the quotient and converting s[i] to a true polynomial. Put differently, it's the conversion from K to L. Then there is a coercion from L to R (but not from K to R).

@embray
Copy link
Contributor Author

embray commented Sep 2, 2016

comment:12

Thanks, that all makes sense. In particular I didn't realize what lift() did.

@vbraun
Copy link
Member

vbraun commented Sep 2, 2016

comment:14

Reviewer name..

@jdemeyer
Copy link

jdemeyer commented Sep 2, 2016

Reviewer: Jeroen Demeyer, Erik Bray

@vbraun
Copy link
Member

vbraun commented Sep 4, 2016

Changed branch from u/jdemeyer/psi2 to bdce5dc

@vbraun vbraun closed this as completed in d76461f Sep 4, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants