-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Move heavy visualization imports outside base namespace imports #4958
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
Move heavy visualization imports outside base namespace imports #4958
Conversation
Importing IPython takes at least >150ms and is only used directly in one function (and then only if it's in jupyter). This is a pretty heavy import to run unconditionally at the module level, because we end up wasting time if IPython is installed even if we're not inside jupyter confirming the module is present despite never being able to use it. This commit moves it to runtime to avoid inside the function to avoid this import penalty, it will add som small overhead to the function but since its not performance critical this is a fine tradeoff.
This commit moves the import of the qiskit visualization module for the pass manager drawer from the module level in qiskit.transpiler.passmanager to a run time import in the draw() method. The visualization module import time is fairly heavy (when matplotlib is installed) because of its usage of matplotlib. By having the import at the module level this forces this import time penaly on just a bare import of qiskit even if no visualization is going to be used. This is because the passmaanger gets pulled in from the top level namespaces of qiskit. To avoid this unecessary overhead this makes it a runtime import so unless you go to use the passmanager.draw() method it won't be imported. This will add some overhead to the draw() method (especially if matplotlib hasn't already been imported) but since visualization methods aren't performance critical and are typically quite slow this isn't a a problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 on the import time improvements.
This takes qiskit.visualization
out of the default set of modules that are loaded by import qiskit
(and so takes it out of tab completion). Is it possible to keep the import time improvement but still load the non-heavy parts of qiskit.visualization
?
It should be possible, but this basically means we have to move any matplotlib import to be at runtime instead of at the module level (and then add visualization back to the top level). The only complexity is there are a couple of places we import |
Moving the visualization import to runtime has a backwards compatibility issue in that the visualization module is no longer imported as part of qiskit. This can potentially break users since visualization functionality would be present without a second import. This reverts this change to avoid that breaking change. A follow-on PR will try to address the import time performance from matplotlib in a different way. This reverts commit bcdb37f.
This reverts commit 2967f0b.
I looked into making matplotlib imports happen at runtime and there is a different backwards compatibility concern around the |
* Make ipython detection occur at runtime Importing IPython takes at least >150ms and is only used directly in one function (and then only if it's in jupyter). This is a pretty heavy import to run unconditionally at the module level, because we end up wasting time if IPython is installed even if we're not inside jupyter confirming the module is present despite never being able to use it. This commit moves it to runtime to avoid inside the function to avoid this import penalty, it will add som small overhead to the function but since its not performance critical this is a fine tradeoff. * Move PassManager.draw() visualization import to runtime This commit moves the import of the qiskit visualization module for the pass manager drawer from the module level in qiskit.transpiler.passmanager to a run time import in the draw() method. The visualization module import time is fairly heavy (when matplotlib is installed) because of its usage of matplotlib. By having the import at the module level this forces this import time penaly on just a bare import of qiskit even if no visualization is going to be used. This is because the passmaanger gets pulled in from the top level namespaces of qiskit. To avoid this unecessary overhead this makes it a runtime import so unless you go to use the passmanager.draw() method it won't be imported. This will add some overhead to the draw() method (especially if matplotlib hasn't already been imported) but since visualization methods aren't performance critical and are typically quite slow this isn't a a problem. * Fix docs build * Revert "Move PassManager.draw() visualization import to runtime" Moving the visualization import to runtime has a backwards compatibility issue in that the visualization module is no longer imported as part of qiskit. This can potentially break users since visualization functionality would be present without a second import. This reverts this change to avoid that breaking change. A follow-on PR will try to address the import time performance from matplotlib in a different way. This reverts commit bcdb37f. * Revert "Fix docs build" This reverts commit 2967f0b. Co-authored-by: Kevin Krsulich <kevin.krsulich@ibm.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit 4cbc751)
… (#4997) * Make ipython detection occur at runtime Importing IPython takes at least >150ms and is only used directly in one function (and then only if it's in jupyter). This is a pretty heavy import to run unconditionally at the module level, because we end up wasting time if IPython is installed even if we're not inside jupyter confirming the module is present despite never being able to use it. This commit moves it to runtime to avoid inside the function to avoid this import penalty, it will add som small overhead to the function but since its not performance critical this is a fine tradeoff. * Move PassManager.draw() visualization import to runtime This commit moves the import of the qiskit visualization module for the pass manager drawer from the module level in qiskit.transpiler.passmanager to a run time import in the draw() method. The visualization module import time is fairly heavy (when matplotlib is installed) because of its usage of matplotlib. By having the import at the module level this forces this import time penaly on just a bare import of qiskit even if no visualization is going to be used. This is because the passmaanger gets pulled in from the top level namespaces of qiskit. To avoid this unecessary overhead this makes it a runtime import so unless you go to use the passmanager.draw() method it won't be imported. This will add some overhead to the draw() method (especially if matplotlib hasn't already been imported) but since visualization methods aren't performance critical and are typically quite slow this isn't a a problem. * Fix docs build * Revert "Move PassManager.draw() visualization import to runtime" Moving the visualization import to runtime has a backwards compatibility issue in that the visualization module is no longer imported as part of qiskit. This can potentially break users since visualization functionality would be present without a second import. This reverts this change to avoid that breaking change. A follow-on PR will try to address the import time performance from matplotlib in a different way. This reverts commit bcdb37f. * Revert "Fix docs build" This reverts commit 2967f0b. Co-authored-by: Kevin Krsulich <kevin.krsulich@ibm.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit 4cbc751) Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
Summary
This PR moves to particularly heavy visualization imports outside of the base
qiskit
namespace import. The first is moving theIPython
import from the single qubit transition visualization out of the module level and into the function. This is only ever used when running inside jupyter (it's used to embed the animation in html so jupyter can display it) and adds unnecessary overhead to the rest of the visualization subpackage import if ipython is installed but not in a jupyter context. The second change made is to move the visualization import for the pass managerdraw()
method to be at run time. Having it at the module level adds a slow matplotlib to the base qiskit namespace because the passmanager gets exposed via the top level api.Details and comments