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

Reduce the use of SymPy lambdify #579

Merged
merged 5 commits into from
May 13, 2021
Merged

Reduce the use of SymPy lambdify #579

merged 5 commits into from
May 13, 2021

Conversation

antalszava
Copy link
Contributor

@antalszava antalszava commented May 12, 2021

Context:
Some optimization tasks using Strawberry Fields were showing increased memory allocation, although no state was being left (i.e., the engine was reset, state objects recreated, etc.).

Parameters in Strawberry Fields might be numeric or symbolic. To represent both, SymPy is used. When using gate parameters that are internally created, Strawberry Fields evaluates the parameter to get the numeric value using SymPy.

Evaluating the parameters depends on the sympy.lambdify function, which internally caches data using linecache. The memory increase was found to be due to this caching.

Description of the Change:
Changes the par_evaluate function which does the parameter evaluation such that:

  • If the SymPy object can be converted to a numeric Python type (float or complex), then we perform the conversion without using sympy.lambdify
  • Otherwise, when using sympy.lambdify we also clear the cache using linecache.

Benefits:

  • Significantly faster parameter evaluation in cases when the use of sympy.lambdify can be avoided
  • No memory increase over time

Possible Drawbacks:
N/A

Related GitHub Issues:
N/A

See profiling data here.

@codecov
Copy link

codecov bot commented May 12, 2021

Codecov Report

Merging #579 (c60dc89) into master (127085e) will increase coverage by 0.00%.
The diff coverage is 100.00%.

@@           Coverage Diff           @@
##           master     #579   +/-   ##
=======================================
  Coverage   98.38%   98.38%           
=======================================
  Files          75       75           
  Lines        8410     8414    +4     
=======================================
+ Hits         8274     8278    +4     
  Misses        136      136           
Impacted Files Coverage Δ
strawberryfields/parameters.py 99.10% <100.00%> (+0.03%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 127085e...c60dc89. Read the comment docs.

@antalszava
Copy link
Contributor Author

Profiling

The following script was profiled for both memory and time:

import strawberryfields as sf
from strawberryfields.ops import *
from strawberryfields.parameters import par_funcs as pf
import numpy as np

eng = sf.Engine("fock", backend_options={"cutoff_dim": 2})

def evx(param, n):
    prog = sf.Program(2)    
    with prog.context as q:
        ntrot = 10
        for i in range(n): 
            step = param/ntrot
            for itrot in range(ntrot):
                
                s = step
                r = pf.asinh(-s / 2)
                theta = 0.5 * pf.atan2(-1.0 / pf.cosh(r), -pf.tanh(r))

                for _ in range(20):
                    # Decomposition of CXgate
                    BSgate(theta, 0) |  (q[0], q[1]),
                    Sgate(r, 0) | q[0],
                    Sgate(-r, 0) | q[1],
                    BSgate(theta + np.pi / 2, 0) | (q[0], q[1]),
                
        state = eng.run(prog).state
        return state.number_expectation([0])
    
parm = 0.05
for i in range(10):

    if eng.run_progs:
        eng.reset()

    res = evx(parm, 40)
    print(i, flush=True)

master branch:

memory:
without_clearing_cache

time: 88.01 secs

calling linecache.clearcache():

with_clearing_cache

time: 87.23 secs

fewer_lambdify branch (calling linecache.clearcache() & no call to lambdify if not symbolic):

time: 34.86 secs

@nquesada nquesada self-requested a review May 12, 2021 21:32
@nquesada
Copy link
Collaborator

@antalszava : don't forget to update the changelog. Also you might want to make the CodeFactor bot happy.

@antalszava antalszava requested a review from josh146 May 12, 2021 21:36
@antalszava antalszava marked this pull request as ready for review May 12, 2021 21:42
Copy link
Member

@josh146 josh146 left a comment

Choose a reason for hiding this comment

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

Great 🕵️ work @antalszava!

Comment on lines +210 to +213
# sympy.lambdify caches data using linecache, if called many times this
# can make up for a lot of memory used. We clear the cache here to
# avoid that.
linecache.clearcache()
Copy link
Member

Choose a reason for hiding this comment

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

Very nice catch @antalszava!

@antalszava antalszava merged commit 39b0265 into master May 13, 2021
@antalszava antalszava deleted the fewer_lambdify branch May 13, 2021 17:11
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.

3 participants