diff --git a/docs/_book.yaml b/docs/_book.yaml index 5a9613622da..00c21a81767 100644 --- a/docs/_book.yaml +++ b/docs/_book.yaml @@ -37,6 +37,8 @@ upper_tabs: path: /cirq/start/start - title: "Cirq Basics" path: /cirq/start/basics + - title: "Best Practices" + path: /cirq/start/best_practices #### TEST UNDERSTANDING #### - heading: "Test understanding" diff --git a/docs/build/gates.ipynb b/docs/build/gates.ipynb index 2ed56a5a086..d9c4ff078f2 100644 --- a/docs/build/gates.ipynb +++ b/docs/build/gates.ipynb @@ -157,6 +157,19 @@ "[Circuits](circuits.ipynb)." ] }, + { + "cell_type": "markdown", + "metadata": { + "id": "yS2UiFDQt-sk" + }, + "source": [ + "## Immutability of Gates and Operations\n", + "\n", + "Gates and Operations in Cirq are considered to be immutable objects. This means that a `cirq.Gate` or `cirq.Operation` should not be modified after its creation. If attributes of these objects need to be modified, a new object should be created.\n", + "\n", + "Modifying these objects in-place could cause unexpected behavior. For instance, changing the qubits of an existing `cirq.Operation` object could cause an existing `cirq.Moment` that contains this object to have operations with overlapping qubits." + ] + }, { "cell_type": "markdown", "metadata": { diff --git a/docs/dev/rfc_process.md b/docs/dev/rfc_process.md index 792c1cda959..5b71ff90d9b 100644 --- a/docs/dev/rfc_process.md +++ b/docs/dev/rfc_process.md @@ -41,7 +41,7 @@ and have a discussion with the maintainers. Mention that you are willing to writ * Make sure to share your doc with cirq-dev@googlegroups.com for comments. * Link the RFC in your issue. 4. Recruiting a sponsor: - * A sponsor must be a maintainer of the project or the product manager (currently Alan Ho). + * A sponsor must be a maintainer of the project or the product manager. * Write a comment in your Github issue that calls out that you are "Looking for a sponsor". A maintainer will mark the issue with a label: "rfc/needs-sponsor". * While it might take some time to get a maintainer to sponsor your RFC, it is essential, as the sponsor will facilitate the process for reviewing your design. * Tips to recruit a sponsor: 1) keep commenting on the issue weekly 2) attend Cirq Cynq and push for a sponsor. diff --git a/docs/simulate/params.ipynb b/docs/simulate/params.ipynb index d114ee5a279..c8916cab935 100644 --- a/docs/simulate/params.ipynb +++ b/docs/simulate/params.ipynb @@ -629,6 +629,21 @@ "You can see that the different flattened parameters have corresponding different results for their simulation." ] }, + { + "cell_type": "markdown", + "metadata": { + "id": "63FrLKWk9_mC" + }, + "source": [ + "### Immutability of Sweeps\n", + "\n", + "Sweeps and parameter resolvers should be considered immutable objects and should not be modified after creation.\n", + "\n", + "Many of these parameter resolvers use dictionaries for internal storage of symbol mappings. Though dictionaries are mutable in python, users should not modify internal mappings of resolvers after creation. Doing so may have undesirable and unpredictable results.\n", + "\n", + "Instead, create a new dictionary and a new parameter resolver object rather than attempting to modify an existing object." + ] + }, { "cell_type": "markdown", "metadata": { diff --git a/docs/start/best_practices.md b/docs/start/best_practices.md new file mode 100644 index 00000000000..134c5b23531 --- /dev/null +++ b/docs/start/best_practices.md @@ -0,0 +1,80 @@ +# Best Practices + +This page describes some of the best practices when using the Cirq library. +Following these guidelines will help you write code that is more performant and +less likely to break from version to version. Many of these rules apply to +other python libraries as well. + +## Use top-level constructs + +The Cirq library is designed so that important user-facing classes and objects +are exposed at the package level. Avoid referencing module names within Cirq. + +For instance, use `cirq.X` and **not** `cirq.ops.X`. The second version will +break if we rename modules or move classes around from version to version. + +## Do not use private member variables of classes + +Any member of a class that is prefixed with an underscore is, by convention, a +private variable and should not be used outside of this class. For instance, +`cirq.XPowGate._dimension` should not be accessed or modified, since it is a +private member of that class. Using or modifying these values could result in +unexpected behavior or in broken code. + +## Do not mutate "immutable" classes + +While python's flexibility allows developers to modify just about anything, it +is bad practice to modify classes that are designed to be immutable. Doing so +can violate assumptions made in other parts of the library. + +In particular, attributes of `cirq.Gate`, `cirq.Operation`, `cirq.Moment`, and +`cirq.ParamResolver` should not be modified after creation. If these objects +need to be modified, a new object should be created instead. + +Violating this principle could cause problems in other parts of the code. For +instance, changing the qubits of an `cirq.Operation` could cause a `cirq.Moment` +that contains this Operation to have two Operations with the same qubits (which +is not allowed). + +Note that `Circuit` objects can be modified, but `FrozenCircuit` objects cannot. + +## Be mindful of exponential scaling + +Many algorithms and procedures in quantum computing scale in an exponential +pattern. Cirq is designed for the noisy intermediate-scale quantum computing +(NISQ) regime. Creating circuits with hundreds or thousands of qubits may +surpass the capabilities of this library. + +Even with smaller numbers of qubits, simulation and other tasks can very quickly +consume resources and time. The difference between a one second and an hour's +computation can be as few as ten qubits. + +## What you see is what you get + +Cirq tries to be as true to the specified circuits as possible, especially with +respect to hardware execution. Cirq highly discourages any hidden automatic +decomposition, compilation, or other modification of a circuit that is unknown +to the user. Any modification or transformation to the circuit should be +initiated by the user of the library. + +This philosophy is important for many use cases. For instance, certain +benchmarking algorithms rely on the fact that gate sequences will not be optimized, +even if the circuit is nominally inefficient. + +Of course, Cirq provides routines and functions for compilation and +transformation of circuits. Users can and should call these routines. However, +Cirq and resulting hardware integrations should not modify the circuits without +the user's "permission". + +## Other style and performance guidelines + +* Use `cirq.CircuitOperation` to more compactly define large, repeated + circuits. This can save space and time for analysis of larger circuits. +* For hardware execution of multiple circuits, prefer using `run_sweep` to + run variants of circuits. When not possible, try using `run_batch`. Using + these methods gives the hardware service the most opportunity to optimize + the execution of circuits and can result in much faster execution. + Read more details on the [Parameter Sweeps](/cirq/simulate/params) page. +* Consider defining and allocating qubits at the beginning of your code or + function, then applying gates and circuits to those qubits. While not + required, this style can produce cleaner code.