Skip to content

Commit

Permalink
Adding parametric compilation for QVM and QPU (#39)
Browse files Browse the repository at this point in the history
* Fixes the plugin to support pyquil 2.16

* bump pyQuil version

* added rewiring

* Fixed qubit measuring order

* store compiled program

* remove partial rewiring

* return partial

* fix wiring key error

* First draft of porting to QubitDevice

* Modifying BasisState such that it uses the wires passed (instead of enumerate); rename CCNOT to Toffoli; fix test for test_qvm

* Fixing qvm and qpu and their tests

* Fixes for the wavelength simulator and tests

* Fixing WavefunctionDevice and NumpyWaveFunction Device; added functionality to raise an error for QVM analytic=True case (test included)

* Increasing shots for QPU tests

* Modifying comments, removing active_wires from test

* Update pennylane_forest/qpu.py

Co-Authored-By: Josh Izaac <josh146@gmail.com>

* Implementing feedback

* Docstring

* First draft

* Using keyword arguments for apply, fixing matrices that were used previously from default.qubit, increasing number of shots such that the stochastic tests will more likely pass

* Adding the lookup table, unit tests and a WIP integration test

* First draft of lookup table and parametric compilation (tests to be modified)

* Modifying the requirements file for the checks

* Making the parameter dictionaries instance attributes, such that there are no conflicts between devices

* Decreasing number of shots and adding flaky tests to stochastic test cases (each is tried 10 times and they need to pass at least once)

* Rename apply_wiring to remap_wires

* Adding timeouts that can be defined for qvms, adding tests

* Adding timeouts that can be defined for qpus, adding tests

* Adding tests for the mutable QNode cases

* Docstrings

* Tweak tests

* Remove no longer used instance attribute _eigs from QVMDevice

* Moving the compilation specific changes to to QVMDevice (as no other ForestDevice would have the concept implemented); restricting the QPU lattices in the qvm and qpu tests such that only 5 qubit devices are chosen; adding tests for coverage (e.g. BasisState not used as first)

* Move Variable attribute init to test

* Docstrings and refactor to apply_rotations

* Refactor QVMDevice such that generate_samples returns samples instead of returning and assigning it to dev._samples; adjusting the tests accordingly

* Docstrings to attributes and apply_rotations method

* Adding comments to parametric compilation logic

* Moving comments before if statements, renaming lookup_table

* Remove unused imports

* Modfying qpu test to be a parametrized test

* Adjust flaky runs

* Add comment to test

* Correct previous error

* Remove parameter_map and parameter_reference_map attributes from ForestDevice -> fixing the resulting failing tests by defining reset method in QVMDevice containing a resetting of these attributes; adding compiled_program property (and underlying attribute) which contains the latest compiled program (regardless of whether parametric compilation is turned on or off); refactor generate_samples and place comments inside; adding parametrized tests; adding tests for compiled_program

* Modify timeout for test where server failed to respond

* Timeout

* Update pennylane_forest/qpu.py

Co-Authored-By: Josh Izaac <josh146@gmail.com>

* Update pennylane_forest/qpu.py

Co-Authored-By: Josh Izaac <josh146@gmail.com>

* Update pennylane_forest/qpu.py

Co-Authored-By: Josh Izaac <josh146@gmail.com>

* Docstrings

* Reverting pennylane version requirement in requirements.txt

* Blacking

* Reverting requirements modification; version can be incremented upon release

Co-authored-by: Josh Izaac <josh146@gmail.com>
  • Loading branch information
antalszava and josh146 committed Feb 1, 2020
1 parent c03085e commit 73369e7
Show file tree
Hide file tree
Showing 12 changed files with 1,287 additions and 673 deletions.
124 changes: 62 additions & 62 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,41 +18,41 @@
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath('..'))
sys.path.insert(0, os.path.abspath('_ext'))
sys.path.insert(0, os.path.abspath(".."))
sys.path.insert(0, os.path.abspath("_ext"))

# -- General configuration ------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
needs_sphinx = '1.6'
needs_sphinx = "1.6"

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
'sphinx.ext.todo',
'sphinx.ext.coverage',
'sphinx.ext.mathjax',
'sphinx.ext.napoleon',
'sphinx.ext.inheritance_diagram',
'sphinx.ext.viewcode',
"sphinx.ext.autodoc",
"sphinx.ext.autosummary",
"sphinx.ext.todo",
"sphinx.ext.coverage",
"sphinx.ext.mathjax",
"sphinx.ext.napoleon",
"sphinx.ext.inheritance_diagram",
"sphinx.ext.viewcode",
]

# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
source_suffix = ".rst"

# The master toctree document.
master_doc = 'index'
master_doc = "index"

# General information about the project.
project = 'PennyLane-Forest'
project = "PennyLane-Forest"
copyright = "Copyright 2018."
author = 'Xanadu and Rigetti Computing.'
author = "Xanadu and Rigetti Computing."

add_module_names = False

Expand All @@ -61,11 +61,12 @@
# built documents.

import pennylane_forest

# The full version, including alpha/beta/rc tags.
release = pennylane_forest.__version__

# The short X.Y version.
version = re.match(r'^(\d+\.\d+)', release).expand(r'\1')
version = re.match(r"^(\d+\.\d+)", release).expand(r"\1")

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand All @@ -75,19 +76,19 @@
language = None

# today_fmt is used as the format for a strftime call.
today_fmt = '%Y-%m-%d'
today_fmt = "%Y-%m-%d"

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]

# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
show_authors = True

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
pygments_style = "sphinx"

# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True
Expand All @@ -103,21 +104,21 @@
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# html_theme_options = {}

# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# html_theme_path = []

# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# html_title = None

# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# html_short_title = None

# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# html_logo = None

# The name of an image file (relative to this directory) to use as a favicon of
# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
Expand All @@ -132,90 +133,90 @@
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []
# html_extra_path = []

# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# html_last_updated_fmt = '%b %d, %Y'

# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# html_use_smartypants = True

# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# This is required for the alabaster theme
# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
#html_sidebars = {
# html_sidebars = {
# '**': [
# 'about.html',
# 'navigation.html',
# 'relations.html', # needs 'show_related': True theme option to display
# 'searchbox.html',
# 'donate.html',
# ]
#}
# }
html_sidebars = {
'**' : [
'logo-text.html',
'searchbox.html',
'globaltoc.html',
"**": [
"logo-text.html",
"searchbox.html",
"globaltoc.html",
# 'sourcelink.html'
]
}

# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# html_additional_pages = {}

# If false, no module index is generated.
#html_domain_indices = True
# html_domain_indices = True

# If false, no index is generated.
#html_use_index = True
# html_use_index = True

# If true, the index is split into individual pages for each letter.
#html_split_index = False
# html_split_index = False

# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# html_show_sourcelink = True

# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# html_show_sphinx = True

# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# html_show_copyright = True

# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# html_use_opensearch = ''

# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# html_file_suffix = None

# Language to be used for generating the HTML full-text search index.
# Sphinx supports the following languages:
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja'
# 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr'
#html_search_language = 'en'
# html_search_language = 'en'

# A dictionary with options for the search language support, empty by default.
# Now only 'ja' uses this config value
#html_search_options = {'type': 'default'}
# html_search_options = {'type': 'default'}

# The name of a javascript file (relative to the configuration directory) that
# implements a search results scorer. If empty, the default will be used.
#html_search_scorer = 'scorer.js'
# html_search_scorer = 'scorer.js'

# Output file base name for HTML help builder.
htmlhelp_basename = 'PennyLaneForestdoc'
htmlhelp_basename = "PennyLaneForestdoc"

# -- Options for HTMLHelp output ------------------------------------------

# Output file base name for HTML help builder.
htmlhelp_basename = 'PennyLaneForestdoc'
htmlhelp_basename = "PennyLaneForestdoc"


# -- Options for LaTeX output ---------------------------------------------
Expand All @@ -224,39 +225,32 @@
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',

# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',

# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',

# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}

latex_additional_files = ['macros.tex']
latex_additional_files = ["macros.tex"]

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'PennyLane-Forest.tex', 'PennyLane-Forest Documentation',
'Xanadu Inc.', 'manual'),
(master_doc, "PennyLane-Forest.tex", "PennyLane-Forest Documentation", "Xanadu Inc.", "manual")
]


# -- Options for manual page output ---------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'pennylane-forest', 'PennyLane-Forest Documentation',
[author], 1)
]
man_pages = [(master_doc, "pennylane-forest", "PennyLane-Forest Documentation", [author], 1)]


# -- Options for Texinfo output -------------------------------------------
Expand All @@ -265,13 +259,19 @@
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'PennyLane-Forest', 'PennyLane-Forest Documentation',
author, 'PennyLane-Forest', 'pyQuil plugin for the PennyLane quantum machine learning library.',
'Miscellaneous'),
(
master_doc,
"PennyLane-Forest",
"PennyLane-Forest Documentation",
author,
"PennyLane-Forest",
"pyQuil plugin for the PennyLane quantum machine learning library.",
"Miscellaneous",
)
]


#============================================================
# ============================================================

# the order in which autodoc lists the documented members
autodoc_member_order = 'bysource'
autodoc_member_order = "bysource"
34 changes: 25 additions & 9 deletions pennylane_forest/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
~~~~~~~~~~~~
"""
import uuid
import abc

import numpy as np

Expand All @@ -44,7 +43,7 @@
# following gates are not supported by PennyLane
from pyquil.gates import S, T, CPHASE00, CPHASE01, CPHASE10, CPHASE, CCNOT, CSWAP, ISWAP, PSWAP

from pennylane import QubitDevice
from pennylane import QubitDevice, DeviceError

from ._version import __version__

Expand Down Expand Up @@ -186,7 +185,7 @@ class ForestDevice(QubitDevice):
_operation_map = pyquil_operation_map
_capabilities = {"model": "qubit", "tensor_observables": True}

def __init__(self, wires, shots=1000, analytic=False, **kwargs):
def __init__(self, wires, shots=1000, analytic=False, **kwargs):
super().__init__(wires, shots, analytic=analytic)
self.analytic = analytic
self.forest_url = kwargs.get("forest_url", pyquil_config.forest_url)
Expand Down Expand Up @@ -244,21 +243,38 @@ def apply(self, operations, **kwargs):

# Apply the circuit operations
for i, operation in enumerate(operations):
# number of wires on device
# map the operation wires to the physical device qubits
wires = self.remap_wires(operation.wires)
par = operation.parameters

if i > 0 and operation.name in ("QubitStateVector", "BasisState"):
raise DeviceError("Operation {} cannot be used after other Operations have already been applied "
"on a {} device.".format(operation.name, self.short_name))

raise DeviceError(
"Operation {} cannot be used after other Operations have already "
"been applied on a {} device.".format(operation.name, self.short_name)
)
self.prog += self._operation_map[operation.name](*par, *wires)

# Apply the circuit rotations
self.prog += self.apply_rotations(rotations)

def apply_rotations(self, rotations):
"""Apply the circuit rotations.
This method serves as an auxiliary method to :meth:`~.ForestDevice.apply`.
Args:
rotations (List[pennylane.Operation]): operations that rotate into the
measurement basis
Returns:
pyquil.Program: the pyquil Program that specifies the corresponding rotations
"""
rotation_operations = Program()
for operation in rotations:
wires = self.remap_wires(operation.wires)
par = operation.parameters
self.prog += self._operation_map[operation.name](*par, *wires)
rotation_operations += self._operation_map[operation.name](*par, *wires)

return rotation_operations

def reset(self):
self.prog = Program()
Expand Down

0 comments on commit 73369e7

Please sign in to comment.