Skip to content

Commit

Permalink
Abstract out auth+device+sampler boilerplate from cirq_google tutoria…
Browse files Browse the repository at this point in the history
…ls (#4286)

Code from the tutorial notebooks has been abstracted out into a function in the `cirq_google` library.
The function goes by the name `cirq_google.engine.engine_sampler.get_device_sampler()`
All the notebooks are being refactored to use this abstraction.
Closes #4260.
  • Loading branch information
AnimeshSinha1309 committed Sep 14, 2021
1 parent 578c956 commit b3fa1bf
Show file tree
Hide file tree
Showing 14 changed files with 264 additions and 469 deletions.
3 changes: 2 additions & 1 deletion cirq-google/cirq_google/engine/engine_sampler.py
Expand Up @@ -11,7 +11,8 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import List, Sequence, TYPE_CHECKING, Union, Optional, cast

from typing import List, TYPE_CHECKING, Union, Optional, cast, Sequence, Tuple

import cirq
from cirq_google import engine
Expand Down
124 changes: 124 additions & 0 deletions cirq-google/cirq_google/engine/qcs_notebook.py
@@ -0,0 +1,124 @@
# Copyright 2019 The Cirq Developers
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import dataclasses
from typing import Union, Optional

import cirq

from cirq_google import (
PhasedFSimEngineSimulator,
QuantumEngineSampler,
SQRT_ISWAP_INV_PARAMETERS,
PhasedFSimCharacterization,
Bristlecone,
get_engine_sampler,
get_engine_device,
)


@dataclasses.dataclass
class QCSObjectsForNotebook:
device: cirq.Device
sampler: Union[PhasedFSimEngineSimulator, QuantumEngineSampler]
signed_in: bool

@property
def is_simulator(self):
return isinstance(self.sampler, PhasedFSimEngineSimulator)


def get_qcs_objects_for_notebook(
project_id: Optional[str] = None, processor_id: Optional[str] = None
) -> QCSObjectsForNotebook:
"""Authenticates on Google Cloud, can return a Device and Simulator.
Args:
project_id: Optional explicit Google Cloud project id. Otherwise,
this defaults to the environment variable GOOGLE_CLOUD_PROJECT.
By using an environment variable, you can avoid hard-coding
personal project IDs in shared code.
processor_id: Engine processor ID (from Cloud console or
``Engine.list_processors``).
Returns:
An instance of DeviceSamplerInfo.
"""

# Converting empty strings to None for form field inputs
if project_id == "":
project_id = None
if processor_id == "":
processor_id = None

google_cloud_signin_failed: bool = False
if project_id is None:
if 'GOOGLE_CLOUD_PROJECT' not in os.environ:
print("No project_id provided and environment variable GOOGLE_CLOUD_PROJECT not set.")
google_cloud_signin_failed = True
else: # pragma: no cover
os.environ['GOOGLE_CLOUD_PROJECT'] = project_id

# Following code runs the user through the Colab OAuth process.

# Checks for Google Application Default Credentials and runs
# interactive login if the notebook is executed in Colab. In
# case the notebook is executed in Jupyter notebook or other
# IPython runtimes, no interactive login is provided, it is
# assumed that the `GOOGLE_APPLICATION_CREDENTIALS` env var is
# set or `gcloud auth application-default login` was executed
# already. For more information on using Application Default Credentials
# see https://cloud.google.com/docs/authentication/production

in_colab = False
try:
from IPython import get_ipython

in_colab = 'google.colab' in str(get_ipython())

if in_colab:
from google.colab import auth

print("Getting OAuth2 credentials.")
print("Press enter after entering the verification code.")
auth.authenticate_user(clear_output=False)
print("Authentication complete.")
else:
print(
"Notebook isn't executed with Colab, assuming "
"Application Default Credentials are setup."
)
except:
pass

# End of Google Colab Authentication segment

device: cirq.Device
sampler: Union[PhasedFSimEngineSimulator, QuantumEngineSampler]
if google_cloud_signin_failed or processor_id is None:
print("Using a noisy simulator.")
sampler = PhasedFSimEngineSimulator.create_with_random_gaussian_sqrt_iswap(
mean=SQRT_ISWAP_INV_PARAMETERS,
sigma=PhasedFSimCharacterization(theta=0.01, zeta=0.10, chi=0.01, gamma=0.10, phi=0.02),
)
device = Bristlecone
else: # pragma: no cover
device = get_engine_device(processor_id)
sampler = get_engine_sampler(processor_id, gate_set_name="sqrt_iswap")
return QCSObjectsForNotebook(
device=device,
sampler=sampler,
signed_in=not google_cloud_signin_failed,
)
27 changes: 27 additions & 0 deletions cirq-google/cirq_google/engine/qcs_notebook_test.py
@@ -0,0 +1,27 @@
# Copyright 2019 The Cirq Developers
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import cirq_google as cg
from cirq_google.engine.qcs_notebook import get_qcs_objects_for_notebook


def test_get_device_sampler():
result = get_qcs_objects_for_notebook()
assert result.device is cg.Bristlecone
assert result.signed_in is False
assert type(result.sampler) is cg.PhasedFSimEngineSimulator
assert result.is_simulator

result = get_qcs_objects_for_notebook("", "")
assert not result.signed_in
2 changes: 1 addition & 1 deletion dev_tools/conf/mypy.ini
Expand Up @@ -5,7 +5,7 @@ follow_imports = silent
ignore_missing_imports = true

# 3rd-party libs for which we don't have stubs
[mypy-apiclient.*,freezegun.*,matplotlib.*,mpl_toolkits,multiprocessing.dummy,oauth2client.*,pandas.*,pytest.*,scipy.*,sortedcontainers.*,setuptools.*,pylatex.*,networkx.*,qiskit.*,pypandoc.*,ply.*,_pytest.*,google.api.*,google.api_core.*,grpc.*,google.oauth2.*,google.protobuf.text_format.*,quimb.*,pyquil.*,google.cloud.*,filelock.*,codeowners.*,tqdm.*,importlib_metadata.*]
[mypy-apiclient.*,freezegun.*,matplotlib.*,mpl_toolkits,multiprocessing.dummy,oauth2client.*,pandas.*,pytest.*,scipy.*,sortedcontainers.*,setuptools.*,pylatex.*,networkx.*,qiskit.*,pypandoc.*,ply.*,_pytest.*,google.api.*,google.api_core.*,grpc.*,google.oauth2.*,google.protobuf.text_format.*,quimb.*,pyquil.*,google.cloud.*,filelock.*,codeowners.*,tqdm.*,importlib_metadata.*,google.colab.*,IPython.*]
follow_imports = silent
ignore_missing_imports = true

Expand Down
63 changes: 6 additions & 57 deletions docs/tutorials/google/calibration_api.ipynb
Expand Up @@ -134,61 +134,10 @@
"\n",
"# The Google Cloud Project id to use.\n",
"project_id = '' #@param {type:\"string\"}\n",
"\n",
"\n",
"use_noisy_simulator = False\n",
"if project_id == '' and 'GOOGLE_CLOUD_PROJECT' not in os.environ:\n",
" print(\"No project_id provided and environment variable \"\n",
" \"GOOGLE_CLOUD_PROJECT not set.\")\n",
" use_noisy_simulator = True\n",
"else: \n",
" os.environ['GOOGLE_CLOUD_PROJECT'] = project_id\n",
"\n",
" def authenticate_user():\n",
" \"\"\"Runs the user through the Colab OAuth process.\n",
"\n",
" Checks for Google Application Default Credentials and runs interactive login \n",
" if the notebook is executed in Colab. In case the notebook is executed in Jupyter notebook\n",
" or other IPython runtimes, no interactive login is provided, it is assumed that the \n",
" `GOOGLE_APPLICATION_CREDENTIALS` env var is set or `gcloud auth application-default login`\n",
" was executed already.\n",
"\n",
" For more information on using Application Default Credentials see \n",
" https://cloud.google.com/docs/authentication/production\n",
" \"\"\"\n",
" in_colab = False\n",
" try:\n",
" from IPython import get_ipython\n",
" in_colab = 'google.colab' in str(get_ipython())\n",
" except: \n",
" # Notebook is not executed within IPython. Assuming external authentication.\n",
" return \n",
"\n",
" if in_colab: \n",
" from google.colab import auth \n",
" print(\"Getting OAuth2 credentials.\")\n",
" print(\"Press enter after entering the verification code.\")\n",
" auth.authenticate_user(clear_output=False)\n",
" print(\"Authentication complete.\")\n",
" else: \n",
" print(\"Notebook is not executed with Colab, assuming Application Default Credentials are setup.\") \n",
"\n",
" authenticate_user()\n",
" print(\"Successful authentication to Google Cloud.\")\n",
"\n",
"processor_id = \"\" #@param {type:\"string\"}\n",
"if use_noisy_simulator or processor_id == \"\":\n",
" print(\"Using a noisy simulator.\")\n",
" sampler = cg.PhasedFSimEngineSimulator.create_with_random_gaussian_sqrt_iswap(\n",
" mean=cg.SQRT_ISWAP_INV_PARAMETERS,\n",
" sigma=cg.PhasedFSimCharacterization(\n",
" theta=0.01, zeta=0.10, chi=0.01, gamma=0.10, phi=0.02\n",
" ),\n",
" )\n",
" device = cg.Bristlecone\n",
"else:\n",
" device = cg.get_engine_device(processor_id)\n",
" sampler = cg.get_engine_sampler(processor_id, gate_set_name=\"sqrt_iswap\")"
"\n",
"from cirq_google.engine.qcs_notebook import get_qcs_objects_for_notebook\n",
"device_sampler = get_qcs_objects_for_notebook(project_id, processor_id)"
]
},
{
Expand Down Expand Up @@ -251,7 +200,7 @@
"outputs": [],
"source": [
"\"\"\"Define your circuit(s) here.\"\"\"\n",
"qubits = cg.line_on_device(device, length=2)\n",
"qubits = cg.line_on_device(device_sampler.device, length=2)\n",
"circuit = cirq.Circuit(cirq.ISWAP.on(*qubits) ** 0.5)\n",
"\n",
"print(\"Example circuit:\", circuit, sep=\"\\n\\n\")"
Expand Down Expand Up @@ -328,7 +277,7 @@
"\n",
"# Characterize the requests on the engine.\n",
"floquet_characterizations = cg.run_calibrations(\n",
" floquet_characterization_requests, sampler\n",
" floquet_characterization_requests, device_sampler.sampler\n",
")"
]
},
Expand Down Expand Up @@ -444,7 +393,7 @@
"\n",
"# Characterize the requests on the engine.\n",
"xeb_characterizations = cg.run_calibrations(\n",
" xeb_characterization_requests, sampler\n",
" xeb_characterization_requests, device_sampler.sampler\n",
")"
]
},
Expand Down
45 changes: 5 additions & 40 deletions docs/tutorials/google/colab.ipynb
Expand Up @@ -187,49 +187,14 @@
}
],
"source": [
"import cirq_google as cg\n",
"\n",
"# The Google Cloud Project id to use.\n",
"project_id = '' #@param {type:\"string\"}\n",
"processor_id = \"\" #@param {type:\"string\"}\n",
"\n",
"if project_id == '':\n",
" import os \n",
" if 'GOOGLE_CLOUD_PROJECT' not in os.environ:\n",
" raise Exception(\"Please setup project_id in this cell or set the `GOOGLE_CLOUD_PROJECT` env var to your project id.\")\n",
" project_id = os.environ['GOOGLE_CLOUD_PROJECT']\n",
"else: \n",
" os.environ['GOOGLE_CLOUD_PROJECT'] = project_id\n",
"\n",
"def authenticate_user():\n",
" \"\"\"Runs the user through the Colab OAuth process.\n",
" \n",
" Checks for Google Application Default Credentials and runs interactive login \n",
" if the notebook is executed in Colab. In case the notebook is executed in Jupyter notebook\n",
" or other IPython runtimes, no interactive login is provided, it is assumed that the \n",
" `GOOGLE_APPLICATION_CREDENTIALS` env var is set or `gcloud auth application-default login`\n",
" was executed already.\n",
" \n",
" For more information on using Application Default Credentials see \n",
" https://cloud.google.com/docs/authentication/production\n",
" \"\"\"\n",
" in_colab = False\n",
" try:\n",
" from IPython import get_ipython\n",
" in_colab = 'google.colab' in str(get_ipython())\n",
" except: \n",
" # Notebook is not executed within IPython. Assuming external authentication.\n",
" return \n",
"\n",
" if in_colab: \n",
" from google.colab import auth \n",
" print(\"Getting OAuth2 credentials.\")\n",
" print(\"Press enter after entering the verification code.\")\n",
" auth.authenticate_user(clear_output=False)\n",
" print(\"Authentication complete.\")\n",
" else: \n",
" print(\"Notebook is not executed with Colab, assuming Application Default Credentials are setup.\") \n",
"\n",
"authenticate_user()\n",
"\n",
"print(\"Successful authentication to Google Cloud.\")"
"from cirq_google.engine.qcs_notebook import get_qcs_objects_for_notebook\n",
"device_sampler = get_qcs_objects_for_notebook(project_id, processor_id)"
]
},
{
Expand Down
44 changes: 3 additions & 41 deletions docs/tutorials/google/compare_to_calibration.ipynb
Expand Up @@ -161,48 +161,10 @@
"source": [
"# The Google Cloud Project id to use.\n",
"project_id = '' #@param {type:\"string\"}\n",
"processor_id = \"\" #@param {type:\"string\"}\n",
"\n",
"if project_id == '':\n",
" import os \n",
" if 'GOOGLE_CLOUD_PROJECT' not in os.environ:\n",
" raise Exception(\"Please setup project_id in this cell or set the `GOOGLE_CLOUD_PROJECT` env var to your project id.\")\n",
" project_id = os.environ['GOOGLE_CLOUD_PROJECT']\n",
"else: \n",
" import os\n",
" os.environ['GOOGLE_CLOUD_PROJECT'] = project_id\n",
"\n",
"def authenticate_user():\n",
" \"\"\"Runs the user through the Colab OAuth process.\n",
"\n",
" Checks for Google Application Default Credentials and runs interactive login \n",
" if the notebook is executed in Colab. In case the notebook is executed in Jupyter notebook\n",
" or other IPython runtimes, no interactive login is provided, it is assumed that the \n",
" `GOOGLE_APPLICATION_CREDENTIALS` env var is set or `gcloud auth application-default login`\n",
" was executed already.\n",
"\n",
" For more information on using Application Default Credentials see \n",
" https://cloud.google.com/docs/authentication/production\n",
" \"\"\"\n",
" in_colab = False\n",
" try:\n",
" from IPython import get_ipython\n",
" in_colab = 'google.colab' in str(get_ipython())\n",
" except: \n",
" # Notebook is not executed within IPython. Assuming external authentication.\n",
" return \n",
"\n",
" if in_colab: \n",
" from google.colab import auth \n",
" print(\"Getting OAuth2 credentials.\")\n",
" print(\"Press enter after entering the verification code.\")\n",
" auth.authenticate_user(clear_output=False)\n",
" print(\"Authentication complete.\")\n",
" else: \n",
" print(\"Notebook is not executed with Colab, assuming Application Default Credentials are setup.\") \n",
"\n",
"authenticate_user()\n",
"\n",
"print(\"Successful authentication to Google Cloud.\")"
"from cirq_google.engine.qcs_notebook import get_qcs_objects_for_notebook\n",
"device_sampler = get_qcs_objects_for_notebook(project_id, processor_id)\n"
]
},
{
Expand Down

0 comments on commit b3fa1bf

Please sign in to comment.