Linter, PEP8 and license header fixes

Fix the warnings raised by pylint and pycodestyle, and add missing
license headers.
This commit is contained in:
Diego M. Rodriguez 2017-12-28 14:32:36 +01:00
parent 02496b5155
commit 2c39096cac
114 changed files with 1639 additions and 1074 deletions

View File

@ -1,23 +1,43 @@
from IBMQuantumExperience import RegisterSizeError
from ._qiskiterror import QISKitError
from ._classicalregister import ClassicalRegister
from ._quantumregister import QuantumRegister
from ._quantumcircuit import QuantumCircuit
from ._gate import Gate
from ._compositegate import CompositeGate
from ._instruction import Instruction
from ._instructionset import InstructionSet
from ._reset import Reset
from ._measure import Measure
import qiskit.extensions.standard
import qiskit.extensions.quantum_initializer
from ._jobprocessor import JobProcessor
from ._quantumjob import QuantumJob
from ._quantumprogram import QuantumProgram
from ._result import Result
from ._util import _check_ibmqe_version
__version__ = '0.4.0'
_check_ibmqe_version()
# -*- coding: utf-8 -*-
# pylint: disable=wrong-import-order
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# 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
#
# http://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.
# =============================================================================
"""Main QISKit public functionality."""
from IBMQuantumExperience import RegisterSizeError
from ._qiskiterror import QISKitError
from ._classicalregister import ClassicalRegister
from ._quantumregister import QuantumRegister
from ._quantumcircuit import QuantumCircuit
from ._gate import Gate
from ._compositegate import CompositeGate
from ._instruction import Instruction
from ._instructionset import InstructionSet
from ._reset import Reset
from ._measure import Measure
# These two qiskit.extensions imports needs to be placed here.
import qiskit.extensions.standard
import qiskit.extensions.quantum_initializer
from ._jobprocessor import JobProcessor
from ._quantumjob import QuantumJob
from ._quantumprogram import QuantumProgram
from ._result import Result
from ._util import _check_ibmqe_version
__version__ = '0.4.0'
_check_ibmqe_version()

View File

@ -102,7 +102,7 @@ class CompositeGate(Gate):
self.data = [gate.q_if(qregs) for gate in self.data]
return self
def c_if(self, c, val):
def c_if(self, classical, val):
"""Add classical control register."""
self.data = [gate.c_if(c, val) for gate in self.data]
self.data = [gate.c_if(classical, val) for gate in self.data]
return self

View File

@ -46,4 +46,5 @@ class Gate(Instruction):
def q_if(self, *qregs):
"""Add controls to this gate."""
# pylint: disable=unused-argument
raise QISKitError("control not implemented")

View File

@ -18,10 +18,11 @@
"""
Quantum computer instruction.
"""
from ._register import Register
from ._qiskiterror import QISKitError
from sympy import Number, Basic
from ._qiskiterror import QISKitError
from ._register import Register
class Instruction(object):
"""Generic quantum computer instruction."""
@ -39,13 +40,13 @@ class Instruction(object):
raise QISKitError("argument not (Register, int) tuple")
self.name = name
self.param = []
for p in param:
if not isinstance(p, (Basic, complex)):
for single_param in param:
if not isinstance(single_param, (Basic, complex)):
# If the item in param is not symbolic and not complex (used
# by InitializeGate), make it symbolic.
self.param.append(Number(p))
self.param.append(Number(single_param))
else:
self.param.append(p)
self.param.append(single_param)
self.arg = arg
self.control = None # tuple (ClassicalRegister, int) for "if"
self.circuit = circuit

View File

@ -1,3 +1,22 @@
# -*- coding: utf-8 -*-
# pylint: disable=redefined-builtin
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# 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
#
# http://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.
# =============================================================================
"""Tools for compiling Quantum Programs."""
import logging
import qiskit.qasm as qasm
@ -47,11 +66,17 @@ def compile(qasm_circuit, basis_gates='u1,u2,u3,cx,id', coupling_map=None,
("q", 2): ("q", 2),
("q", 3): ("q", 3)
}
get_layout (bool): flag for returning the layout.
format (str): The target format of the compilation:
{'dag', 'json', 'qasm'}
Returns:
Compiled circuit
object: If get_layout == False, the compiled circuit in the specified
format. If get_layout == True, a tuple is returned, with the
second element being the layout.
Raises:
QISKitCompilerError: if the format is not valid.
"""
compiled_dag_circuit = _unroller_code(qasm_circuit,
basis_gates=basis_gates)
@ -84,7 +109,7 @@ def compile(qasm_circuit, basis_gates='u1,u2,u3,cx,id', coupling_map=None,
elif format == 'qasm':
compiled_circuit = compiled_dag_circuit.qasm()
else:
raise QiskitCompilerError('unrecognized circuit format')
raise QISKitCompilerError('unrecognized circuit format')
if get_layout:
return compiled_circuit, final_layout
@ -98,12 +123,11 @@ def _unroller_code(qasm_circuit, basis_gates=None):
This is an internal function.
Args:
qasm_circuit: a circuit representation as qasm text.
qasm_circuit (str): a circuit representation as qasm text.
basis_gates (str): a comma seperated string and are the base gates,
which by default are: u1,u2,u3,cx,id
Return:
dag_ciruit (dag object): a dag representation of the circuit
unrolled to basis gates
object: a dag representation of the circuit unrolled to basis gates
"""
if not basis_gates:
basis_gates = "u1,u2,u3,cx,id" # QE target basis
@ -122,7 +146,7 @@ def load_unroll_qasm_file(filename, basis_gates='u1,u2,u3,cx,id'):
filename (str): a string for the filename including its location.
basis_gates (str): basis to unroll circuit to.
Returns:
Returns a unrolled QuantumCircuit object
object: Returns a unrolled QuantumCircuit object
"""
# create Program object Node (AST)
program_node_circuit = qasm.Qasm(filename=filename).parse()
@ -140,12 +164,12 @@ def dag2json(dag_circuit, basis_gates='u1,u2,u3,cx,id'):
function.
Args:
dag_ciruit (dag object): a dag representation of the circuit.
dag_circuit (QuantumCircuit): a dag representation of the circuit.
basis_gates (str): a comma seperated string and are the base gates,
which by default are: u1,u2,u3,cx,id
Returns:
the json version of the dag
json: the json version of the dag
"""
# TODO: Jay: I think this needs to become a method like .qasm() for the DAG.
try:
@ -158,6 +182,7 @@ def dag2json(dag_circuit, basis_gates='u1,u2,u3,cx,id'):
json_circuit = unroller.execute()
return json_circuit
class QiskitCompilerError(QISKitError):
class QISKitCompilerError(QISKitError):
"""Exceptions raised during compilation"""
pass

View File

@ -176,6 +176,9 @@ class QuantumCircuit(object):
def measure(self, qubit, cbit):
"""Measure quantum bit into classical bit (tuples).
Returns:
Gate: the attached measure gate.
Raises:
QISKitError: if qubit is not in this circuit or bad format;
if cbit is not in this circuit or not creg.

View File

@ -1,9 +1,27 @@
# -*- coding: utf-8 -*-
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# 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
#
# http://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.
# =============================================================================
"""Quantum Job class"""
import random
import string
from qiskit import _openquantumcompiler as openquantumcompiler
import qiskit.backends as backends
class QuantumJob():
"""Creates a quantum circuit job
@ -14,54 +32,27 @@ class QuantumJob():
# TODO We need to create more tests for checking all possible inputs.
def __init__(self, circuits, backend='local_qasm_simulator',
circuit_config=None, seed=None,
resources={'max_credits':10, 'wait':5, 'timeout':120},
resources=None,
shots=1024, names=None,
do_compile=False, preformatted=False):
"""
Args:
circuits (QuantumCircuit | list(QuantumCircuit) | qobj):
circuits (QuantumCircuit or list(QuantumCircuit)):
QuantumCircuit or list of QuantumCircuit. If preformatted=True,
this is a raw qobj.
backend (str): The backend to run the circuit on.
timeout (float): Timeout for job in seconds.
circuit_config (dict): Circuit configuration.
seed (int): The intial seed the simulatros use.
resources (dict): Resource requirements of job.
coupling_map (dict): A directed graph of coupling::
{
control(int):
[
target1(int),
target2(int),
, ...
],
...
}
eg. {0: [2], 1: [2], 3: [2]}
initial_layout (dict): A mapping of qubit to qubit::
{
("q", strart(int)): ("q", final(int)),
...
}
eg.
{
("q", 0): ("q", 0),
("q", 1): ("q", 1),
("q", 2): ("q", 2),
("q", 3): ("q", 3)
}
shots (int): the number of shots
circuit_type (str): "compiled_dag" or "uncompiled_dag" or
"quantum_circuit"
names (str | list(str)): names/ids for circuits
preformated (bool): the objects in circuits are already compiled
names (str or list(str)): names/ids for circuits
do_compile (boolean): compile flag.
preformatted (bool): the objects in circuits are already compiled
and formatted (qasm for online, json for local). If true the
parameters "names" and "circuit_config" must also be defined
of the same length as "circuits".
"""
resources = resources or {'max_credits': 10, 'wait': 5, 'timeout': 120}
if isinstance(circuits, list):
self.circuits = circuits
else:

View File

@ -1,4 +1,7 @@
# -*- coding: utf-8 -*-
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# 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
@ -11,10 +14,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# =============================================================================
"""
Qasm Program Class
"""
# pylint: disable=line-too-long
import random
import json
import logging
@ -193,7 +197,8 @@ class QuantumProgram(object):
size (int): the size of the quantum register
Returns:
QuantumRegister: internal reference to a quantum register in __quantum_registers
QuantumRegister: internal reference to a quantum register in
__quantum_registers
Raises:
QISKitError: if the register already exists in the program.
@ -272,7 +277,8 @@ class QuantumProgram(object):
name (str): the name of the classical register
size (int): the size of the classical register
Returns:
ClassicalRegister: internal reference to a classical register in __classical_registers
ClassicalRegister: internal reference to a classical register
in __classical_registers
Raises:
QISKitError: if the register already exists in the program.
@ -348,13 +354,14 @@ class QuantumProgram(object):
Args:
name (str): the name of the circuit.
qregisters (list(QuantumRegister)): is an Array of Quantum Registers by object
reference
cregisters (list(ClassicalRegister)): is an Array of Classical Registers by
object reference
qregisters (list(QuantumRegister)): is an Array of Quantum
Registers by object reference
cregisters (list(ClassicalRegister)): is an Array of Classical
Registers by object reference
Returns:
QuantumCircuit: A quantum circuit is created and added to the Quantum Program
QuantumCircuit: A quantum circuit is created and added to the
Quantum Program
"""
if not qregisters:
qregisters = []
@ -389,7 +396,8 @@ class QuantumProgram(object):
Args:
name (str): the name of the circuit to add.
quantum_circuit (QuantumCircuit): a quantum circuit to add to the program-name
quantum_circuit (QuantumCircuit): a quantum circuit to add to the
program-name
"""
for qname, qreg in quantum_circuit.get_qregs().items():
self.create_quantum_register(qname, len(qreg))
@ -418,7 +426,7 @@ class QuantumProgram(object):
if not name:
name = os.path.splitext(os.path.basename(qasm_file))[0]
node_circuit = qasm.Qasm(filename=qasm_file).parse() # Node (AST)
logger.info("circuit name: " + name)
logger.info("circuit name: %s", name)
logger.info("******************************")
logger.info(node_circuit.qasm())
# current method to turn it a DAG quantum circuit.
@ -446,7 +454,7 @@ class QuantumProgram(object):
# Get a random name if none is given
name = "".join([random.choice(string.ascii_letters+string.digits)
for n in range(10)])
logger.info("circuit name: " + name)
logger.info("circuit name: %s", name)
logger.info("******************************")
logger.info(node_circuit.qasm())
# current method to turn it a DAG quantum circuit.
@ -608,9 +616,9 @@ class QuantumProgram(object):
'project': project
}
for k, v in config_dict.items():
self.__api.config[k] = v
self.__api_config['config'][k] = v
for key, value in config_dict.items():
self.__api.config[key] = value
self.__api_config['config'][key] = value
def get_api_config(self):
"""Return the program specs."""
@ -829,6 +837,8 @@ class QuantumProgram(object):
cmap = configuration[key]
configuration_edit[new_key] = cmap
return configuration_edit
raise LookupError('Configuration for %s could not be found.' %
backend)
else:
return qiskit.backends.get_backend_configuration(backend)
@ -1010,20 +1020,20 @@ class QuantumProgram(object):
if backend == 'ibmqx_hpc_qasm_simulator':
if hpc is None:
logger.info('ibmqx_hpc_qasm_simulator backend needs HPC '
'parameter. Setting defaults to hpc.multi_shot_optimization '
'= true and hpc.omp_num_threads = 16')
'parameter. Setting defaults to hpc.multi_shot_optimization '
'= true and hpc.omp_num_threads = 16')
hpc = {'multi_shot_optimization': True, 'omp_num_threads': 16}
if not all (key in hpc for key in
('multi_shot_optimization','omp_num_threads')):
if not all(key in hpc for key in
('multi_shot_optimization', 'omp_num_threads')):
raise QISKitError('Unknown HPC parameter format!')
qobj['config']['hpc'] = hpc
elif hpc is not None:
logger.info('HPC paramter is only available for '
'ibmqx_hpc_qasm_simulator. You are passing an HPC parameter '
'but you are not using ibmqx_hpc_qasm_simulator, so we will '
'ignore it.')
'ibmqx_hpc_qasm_simulator. You are passing an HPC parameter '
'but you are not using ibmqx_hpc_qasm_simulator, so we will '
'ignore it.')
hpc = None
qobj['circuits'] = []
@ -1033,8 +1043,8 @@ class QuantumProgram(object):
basis_gates = backend_conf['basis_gates']
elif len(basis_gates.split(',')) < 2:
# catches deprecated basis specification like 'SU2+CNOT'
logger.warn('encountered deprecated basis specification: '
'"{}" substituting u1,u2,u3,cx,id'.format(basis_gates))
logger.warning('encountered deprecated basis specification: '
'"%s" substituting u1,u2,u3,cx,id', str(basis_gates))
basis_gates = 'u1,u2,u3,cx,id'
if not coupling_map:
coupling_map = backend_conf['coupling_map']
@ -1171,7 +1181,8 @@ class QuantumProgram(object):
if qobj["circuits"][index]['name'] == name:
return qobj["circuits"][index]["config"]
except KeyError:
raise QISKitError('No compiled configurations for circuit "{0}"'.format(name))
pass
raise QISKitError('No compiled configurations for circuit "{0}"'.format(name))
def get_compiled_qasm(self, qobj, name):
"""Return the compiled cricuit in qasm format.
@ -1191,7 +1202,8 @@ class QuantumProgram(object):
if qobj["circuits"][index]['name'] == name:
return qobj["circuits"][index]["compiled_circuit_qasm"]
except KeyError:
raise QISKitError('No compiled qasm for circuit "{0}"'.format(name))
pass
raise QISKitError('No compiled qasm for circuit "{0}"'.format(name))
###############################################################
# methods to run quantum programs
@ -1291,8 +1303,8 @@ class QuantumProgram(object):
q_job_list = []
for qobj in qobj_list:
q_job = QuantumJob(qobj, preformatted=True, resources={
'max_credits':qobj['config']['max_credits'], 'wait':wait,
'timeout':timeout})
'max_credits': qobj['config']['max_credits'], 'wait': wait,
'timeout': timeout})
q_job_list.append(q_job)
job_processor = JobProcessor(q_job_list, max_workers=5,

View File

@ -1,7 +1,26 @@
# -*- coding: utf-8 -*-
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# 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
#
# http://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.
# =============================================================================
"""Module for working with Results."""
import copy
import numpy
from qiskit._qiskiterror import QISKitError
from qiskit import RegisterSizeError
class Result(object):
""" Result Class.
@ -41,7 +60,7 @@ class Result(object):
"""Get the status of the run.
Returns:
the status of the results.
string: the status of the results.
"""
return self._result['status']
@ -57,7 +76,9 @@ class Result(object):
Arg:
other (Result): a Result object to append.
Returns:
The current object with appended results.
Result: The current object with appended results.
Raises:
QISKitError: if the Results cannot be combined.
"""
if self._qobj['config'] == other._qobj['config']:
if isinstance(self._qobj['id'], str):
@ -78,7 +99,7 @@ class Result(object):
Arg:
other (Result): a Result object to combine.
Returns:
A new Result object consisting of combined objects.
Result: A new Result object consisting of combined objects.
"""
ret = copy.deepcopy(self)
ret += other
@ -94,8 +115,8 @@ class Result(object):
def circuit_statuses(self):
"""Return statuses of all circuits
Return:
List of status result strings.
Returns:
list(str): List of status result strings.
"""
return [circuit_result['status']
for circuit_result in self._result['result']]
@ -105,6 +126,8 @@ class Result(object):
Args:
icircuit (int): index of circuit
Returns:
string: the status of the circuit.
"""
return self._result['result'][icircuit]['status']
@ -112,7 +135,7 @@ class Result(object):
"""Return the job id assigned by the api if this is a remote job.
Returns:
a string containing the job id.
string: a string containing the job id.
"""
return self._result['job_id']
@ -123,7 +146,9 @@ class Result(object):
name (str): the name of the quantum circuit.
Returns:
A text version of the qasm file that has been run.
string: A text version of the qasm file that has been run.
Raises:
QISKitError: if the circuit was not found.
"""
try:
qobj = self._qobj
@ -131,7 +156,8 @@ class Result(object):
if qobj["circuits"][index]['name'] == name:
return qobj["circuits"][index]["compiled_circuit_qasm"]
except KeyError:
raise QISKitError('No qasm for circuit "{0}"'.format(name))
pass
raise QISKitError('No qasm for circuit "{0}"'.format(name))
def get_data(self, name):
"""Get the data of circuit name.
@ -165,11 +191,12 @@ class Result(object):
name (str): the name of the quantum circuit.
Returns:
A dictionary of data for the different backends.
dict: A dictionary of data for the different backends.
Raises:
If there's an error the function will throw a QISKitError or a
RegisterSizeError.
QISKitError: if there is no data for the circuit, or an unhandled
error occurred while fetching the data.
Exception: if a handled error occurred while fetching the data.
"""
if self._is_error():
exception = self._result['result']
@ -184,7 +211,8 @@ class Result(object):
if qobj['circuits'][index]['name'] == name:
return self._result['result'][index]['data']
except (KeyError, TypeError):
raise QISKitError('No data for circuit "{0}"'.format(name))
pass
raise QISKitError('No data for circuit "{0}"'.format(name))
def get_counts(self, name):
"""Get the histogram data of circuit name.
@ -197,6 +225,9 @@ class Result(object):
Returns:
Dictionary: Counts {00000: XXXX, 00001: XXXXX}.
Raises:
QISKitError: if there are no counts for the circuit.
"""
try:
return self.get_data(name)['counts']
@ -248,12 +279,12 @@ class Result(object):
xvals: mx1 array of the circuit xvals
"""
ncircuits = len(self._qobj['circuits'])
#Is this the best way to get the number of qubits?
# Is this the best way to get the number of qubits?
nqubits = self._qobj['circuits'][0]['compiled_circuit']['header']['number_of_qubits']
qubitpol = numpy.zeros([ncircuits, nqubits], dtype=float)
xvals = numpy.zeros([ncircuits], dtype=float)
#build Z operators for each qubit
# build Z operators for each qubit
z_dicts = []
for qubit_ind in range(nqubits):
z_dicts.append(dict())
@ -263,11 +294,12 @@ class Result(object):
if new_key[nqubits-qubit_ind-1] == '1':
z_dicts[-1][new_key] = 1
#go through each circuit and for eqch qubit and apply the operators using "average_data"
# go through each circuit and for eqch qubit and apply the operators using "average_data"
for circuit_ind in range(ncircuits):
if not xvals_dict is None:
if xvals_dict:
xvals[circuit_ind] = xvals_dict[self._qobj['circuits'][circuit_ind]['name']]
for qubit_ind in range(nqubits):
qubitpol[circuit_ind, qubit_ind] = self.average_data(self._qobj['circuits'][circuit_ind]['name'], z_dicts[qubit_ind])
qubitpol[circuit_ind, qubit_ind] = self.average_data(
self._qobj['circuits'][circuit_ind]['name'], z_dicts[qubit_ind])
return qubitpol, xvals

View File

@ -22,6 +22,7 @@ from unittest.mock import patch
API_NAME = 'IBMQuantumExperience'
logger = logging.getLogger(__name__)
def _check_ibmqe_version():
"""Check if the available IBMQuantumExperience version is the required one.

View File

@ -1,3 +1,21 @@
# -*- coding: utf-8 -*-
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# 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
#
# http://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.
# =============================================================================
"""Utilities for using backends."""
from ._basebackend import BaseBackend
from ._backendutils import (get_backend_class,
get_backend_instance,

View File

@ -1,15 +1,33 @@
"""backend functions for registration, information, etc."""
from collections import namedtuple
# -*- coding: utf-8 -*-
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# 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
#
# http://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.
# =============================================================================
"""Backend functions for registration, information, etc."""
import importlib
import inspect
import logging
import os
import pkgutil
import logging
import re
from collections import namedtuple
from .. import QISKitError
from ._basebackend import BaseBackend
from qiskit import mapper
from ._basebackend import BaseBackend
from .. import QISKitError
logger = logging.getLogger(__name__)
@ -33,6 +51,7 @@ as its contents are a combination of:
FIRST_CAP_RE = re.compile('(.)([A-Z][a-z]+)')
ALL_CAP_RE = re.compile('([a-z0-9])([A-Z])')
def discover_local_backends(directory=os.path.dirname(__file__)):
"""This function attempts to discover all backend modules.
@ -65,10 +84,10 @@ def discover_local_backends(directory=os.path.dirname(__file__)):
except QISKitError:
# Ignore backends that could not be initialized.
logger.info(
'backend {} could not be initialized'.format(
fullname))
'backend %s could not be initialized', fullname)
return backend_name_list
def discover_remote_backends(api):
"""Discover backends available on the Quantum Experience
@ -108,11 +127,13 @@ def discover_remote_backends(api):
_REGISTERED_BACKENDS[backend_name] = registered_backend
return backend_name_list
def _snake_case_to_camel_case(name):
"""Return a snake case string from a camelcase string."""
string_1 = FIRST_CAP_RE.sub(r'\1_\2', name)
return ALL_CAP_RE.sub(r'\1_\2', string_1).lower()
def update_backends(api=None):
"""Update registered backends.
@ -131,6 +152,7 @@ def update_backends(api=None):
backend_name_list += discover_remote_backends(api)
return backend_name_list
def register_backend(cls, configuration=None):
"""Register a backend in the list of available backends.
@ -141,7 +163,7 @@ def register_backend(cls, configuration=None):
* the backend is not already registered.
Args:
cls (BaseBackend): a subclass of BaseBackend that contains a backend
cls (class): a subclass of BaseBackend that contains a backend
configuration (dict): backend configuration to use instead of class'
default.
@ -180,6 +202,7 @@ def register_backend(cls, configuration=None):
return backend_name
def deregister_backend(backend_name):
"""Remove backend from list of available backens
@ -209,6 +232,7 @@ def get_backend_class(backend_name):
except KeyError:
raise LookupError('backend "{}" is not available'.format(backend_name))
def get_backend_instance(backend_name):
"""Return a backend instance for the named backend.
@ -228,6 +252,7 @@ def get_backend_instance(backend_name):
return registered_backend.cls(
configuration=registered_backend.configuration)
def get_backend_configuration(backend_name):
"""Return the configuration for the named backend.

View File

@ -1,3 +1,20 @@
# -*- coding: utf-8 -*-
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# 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
#
# http://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.
# =============================================================================
"""This module implements the abstract base class for backend modules.
To create add-on backend modules subclass the Backend class in this module.
@ -7,6 +24,7 @@ from abc import ABC, abstractmethod
class BaseBackend(ABC):
"""Base class for backends."""
@abstractmethod
def __init__(self, configuration=None):
"""Base class for backends.
@ -25,6 +43,7 @@ class BaseBackend(ABC):
@abstractmethod
def run(self, q_job):
"""Run a QuantumJob on the the backend."""
pass
@property

View File

@ -1,3 +1,24 @@
# -*- coding: utf-8 -*-
# pylint: disable=unused-import
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# 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
#
# http://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.
# =============================================================================
"""Backend for the Project Q C++ simulator."""
import itertools
import operator
import random
@ -42,7 +63,10 @@ class ProjectQSimulator(BaseBackend):
"""
Args:
configuration (dict): backend configuration
Raises:
ImportError: if the Project Q simulator is not available.
"""
super(ProjectQSimulator, self).__init__(configuration)
if CppSim is None:
logger.info('Project Q C++ simulator unavailable.')
raise ImportError('Project Q C++ simulator unavailable.')
@ -59,6 +83,15 @@ class ProjectQSimulator(BaseBackend):
else:
self._configuration = configuration
# Define the attributes inside __init__.
self._number_of_qubits = 0
self._number_of_clbits = 0
self._quantum_state = 0
self._classical_state = 0
self._seed = None
self._shots = 0
self._sim = None
def run(self, q_job):
"""Run circuits in q_job"""
# Generating a string id for the job
@ -85,7 +118,7 @@ class ProjectQSimulator(BaseBackend):
circuit (dict): JSON circuit from qobj circuits list
Returns:
A dictionary of results which looks something like::
dict: A dictionary of results which looks something like::
{
"data":
@ -95,14 +128,17 @@ class ProjectQSimulator(BaseBackend):
},
"status": --status (string)--
}
Raises:
SimulatorError: if an error occurred.
"""
# pylint: disable=expression-not-assigned,pointless-statement
ccircuit = circuit['compiled_circuit']
self._number_of_qubits = ccircuit['header']['number_of_qubits']
self._number_of_clbits = ccircuit['header']['number_of_clbits']
self._quantum_state = 0
self._classical_state = 0
cl_reg_index = [] # starting bit index of classical register
cl_reg_nbits = [] # number of bits in classical register
cl_reg_index = [] # starting bit index of classical register
cl_reg_nbits = [] # number of bits in classical register
clbit_index = 0
qobj_quregs = OrderedDict(_get_register_specs(
ccircuit['header']['qubit_labels']))
@ -117,14 +153,14 @@ class ProjectQSimulator(BaseBackend):
if circuit['config']['seed'] is not None:
self._sim._simulator = CppSim(circuit['config']['seed'])
outcomes = []
for shot in range(self._shots):
for _ in range(self._shots):
self._quantum_state = np.zeros(1 << self._number_of_qubits,
dtype=complex)
self._quantum_state[0] = 1
# initialize starting state
self._classical_state = 0
unmeasured_qubits = list(range(self._number_of_qubits))
projq_qureg_dict = OrderedDict(((key,eng.allocate_qureg(size))
projq_qureg_dict = OrderedDict(((key, eng.allocate_qureg(size))
for key, size in
qobj_quregs.items()))
qureg = [qubit for sublist in projq_qureg_dict.values()
@ -148,11 +184,11 @@ class ProjectQSimulator(BaseBackend):
Ry(params[0]) | qubit
Rz(params[1]) | qubit
elif operation['name'] in ['u1']:
params = operation['params']
params = operation['params']
qubit = qureg[operation['qubits'][0]]
Rz(params[0]) | qubit
elif operation['name'] in ['u2']:
params = operation['params']
params = operation['params']
qubit = qureg[operation['qubits'][0]]
Rz(params[1] - np.pi/2) | qubit
Rx(np.pi/2) | qubit
@ -188,7 +224,7 @@ class ProjectQSimulator(BaseBackend):
# Check if reset
elif operation['name'] == 'reset':
qubit = operation['qubits'][0]
raise SimulatorError('Reset operation not yet implemented '+
raise SimulatorError('Reset operation not yet implemented '
'for ProjectQ C++ backend')
elif operation['name'] == 'barrier':
pass
@ -201,7 +237,7 @@ class ProjectQSimulator(BaseBackend):
qubit = qureg[ind]
Measure | qubit
eng.flush()
# Turn classical_state (int) into bit string
# Turn classical_state (int) into bit string
state = format(self._classical_state, 'b')
outcomes.append(state.zfill(self._number_of_clbits))
# Return the results
@ -210,12 +246,14 @@ class ProjectQSimulator(BaseBackend):
counts, cl_reg_index, cl_reg_nbits)}
if self._shots == 1:
data['quantum_state'] = self._quantum_state
data['classical_state'] = self._classical_state,
data['classical_state'] = self._classical_state
return {'data': data, 'status': 'DONE'}
def _get_register_specs(bit_labels):
"""
Get the number and size of unique registers from bit_labels list.
Get the number and size of unique registers from bit_labels list with an
iterator of register_name:size pairs.
Args:
bit_labels (list): this list is of the form::
@ -224,16 +262,16 @@ def _get_register_specs(bit_labels):
which indicates a register named "reg1" of size 2
and a register named "reg2" of size 1. This is the
format of classic and quantum bit labels in qobj
format of classic and quantum bit labels in qobj
header.
Returns:
iterator of register_name:size pairs.
Yields:
tuple: pairs of (register_name, size)
"""
it = itertools.groupby(bit_labels, operator.itemgetter(0))
for register_name, sub_it in it:
iterator = itertools.groupby(bit_labels, operator.itemgetter(0))
for register_name, sub_it in iterator:
yield register_name, max(ind[1] for ind in sub_it) + 1
def _format_result(counts, cl_reg_index, cl_reg_nbits):
"""Format the result bit string.
@ -241,11 +279,11 @@ def _format_result(counts, cl_reg_index, cl_reg_nbits):
at register divisions.
Args:
counts : dictionary of counts e.g. {'1111': 1000, '0000':5}
cl_reg_index: starting bit index of classical register
cl_reg_nbits: total amount of bits in classical register
counts (dict): dictionary of counts e.g. {'1111': 1000, '0000':5}
cl_reg_index (list): starting bit index of classical register
cl_reg_nbits (list): total amount of bits in classical register
Returns:
spaces inserted into dictionary keys at register boundries.
dict: spaces inserted into dictionary keys at register boundaries.
"""
fcounts = {}
for key, value in counts.items():
@ -255,4 +293,3 @@ def _format_result(counts, cl_reg_index, cl_reg_nbits):
new_key.insert(0, key[-(index+nbits):-index])
fcounts[' '.join(new_key)] = value
return fcounts

View File

@ -1,3 +1,20 @@
# -*- coding: utf-8 -*-
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# 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
#
# http://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.
# =============================================================================
"""Interface to a fast C++ QASM simulator.
Authors: Erick Winston <ewinston@us.ibm.com>
@ -28,6 +45,7 @@ class QasmCppSimulator(BaseBackend):
Raises:
FileNotFoundError: if executable, 'qasm_simulator', is not on path
"""
super(QasmCppSimulator, self).__init__(configuration)
if configuration is None:
self._configuration = {'name': 'local_qasm_cpp_simulator',
'url': 'https://github.com/IBM/qiskit-sdk-py',
@ -36,8 +54,7 @@ class QasmCppSimulator(BaseBackend):
'local': True,
'description': 'A c++ simulator for qasm files',
'coupling_map': 'all-to-all',
'basis_gates': 'u1,u2,u3,cx,id'
}
'basis_gates': 'u1,u2,u3,cx,id'}
else:
self._configuration = configuration
self._is_simulator = self._configuration['simulator']
@ -62,6 +79,15 @@ class QasmCppSimulator(BaseBackend):
cmd = '"{0}" or "{1}" '.format(self._exe, './' + self._exe)
raise FileNotFoundError(cmd)
# Define attributes in __init__.
self._threads = 0
self._default_shots = 0
self.result = None
self._cpp_backend = None
self.cin_dict = None
self.config = None
self._default_seed = 0
def run(self, q_job):
"""
Run simulation on C++ simulator.
@ -114,7 +140,7 @@ class QasmCppSimulator(BaseBackend):
stdin=PIPE, stdout=PIPE, stderr=PIPE) as proc:
cin = json.dumps(qobj).encode()
cout, cerr = proc.communicate(cin)
if len(cerr) == 0:
if not cerr:
# no error messages, load std::cout
cresult = json.loads(cout.decode())
cresult['job_id'] = job_id
@ -134,6 +160,11 @@ class QasmCppSimulator(BaseBackend):
Args:
circuit (dict): JSON circuit from qobj circuits list
Raises:
TypeError: if the seed is not valid.
SimulatorError: if the cpp simulator failed.
Returns:
Result: Result object.
"""
self.cin_dict = {'qasm': circuit['compiled_circuit'],
'config': self.config}
@ -170,7 +201,7 @@ class QasmCppSimulator(BaseBackend):
stdin=PIPE, stdout=PIPE, stderr=PIPE) as proc:
cin = json.dumps(self.cin_dict).encode()
cout, cerr = proc.communicate(cin)
if len(cerr) == 0:
if not cerr:
# no error messages, load std::cout
cresult = json.loads(cout.decode())
# convert possible complex valued result fields

View File

@ -35,9 +35,9 @@ and
results['data']['classical_state']
where 'quantum_state' is a 2\ :sup:`n` complex numpy array representing the
where 'quantum_state' is a 2 :sup:`n` complex numpy array representing the
quantum state vector and 'classical_state' is an integer representing
the state of the classical registors.
the state of the classical registers.
if shots > 1
@ -105,15 +105,17 @@ if shots > 1
}
"""
import uuid
import numpy as np
import random
import uuid
from collections import Counter
import json
from ._simulatortools import single_gate_matrix
from ._simulatorerror import SimulatorError
import numpy as np
from qiskit._result import Result
from qiskit.backends._basebackend import BaseBackend
from ._simulatorerror import SimulatorError
from ._simulatortools import single_gate_matrix
# TODO add ["status"] = 'DONE', 'ERROR' especitally for empty circuit error
# does not show up
@ -126,6 +128,7 @@ class QasmSimulator(BaseBackend):
Args:
configuration (dict): backend configuration
"""
super(QasmSimulator, self).__init__(configuration)
if configuration is None:
self._configuration = {
'name': 'local_qasm_simulator',
@ -138,9 +141,16 @@ class QasmSimulator(BaseBackend):
}
else:
self._configuration = configuration
self._local_random = random.Random()
# Define attributes in __init__.
self._classical_state = 0
self._quantum_state = 0
self._number_of_cbits = 0
self._number_of_qubits = 0
self._shots = 0
@staticmethod
def _index1(b, i, k):
"""Magic index1 function.
@ -293,7 +303,7 @@ class QasmSimulator(BaseBackend):
circuit (dict): JSON circuit from qobj circuits list
Returns:
A dictionary of results which looks something like::
dict: A dictionary of results which looks something like::
{
"data":
@ -303,14 +313,16 @@ class QasmSimulator(BaseBackend):
},
"status": --status (string)--
}
Raises:
SimulatorError: if an error occurred.
"""
ccircuit = circuit['compiled_circuit']
self._number_of_qubits = ccircuit['header']['number_of_qubits']
self._number_of_cbits = ccircuit['header']['number_of_clbits']
self._quantum_state = 0
self._classical_state = 0
cl_reg_index = [] # starting bit index of classical register
cl_reg_nbits = [] # number of bits in classical register
cl_reg_index = [] # starting bit index of classical register
cl_reg_nbits = [] # number of bits in classical register
cbit_index = 0
for cl_reg in ccircuit['header']['clbit_labels']:
cl_reg_nbits.append(cl_reg[1])
@ -321,7 +333,7 @@ class QasmSimulator(BaseBackend):
else:
self._local_random.seed(circuit['config']['seed'])
outcomes = []
for shot in range(self._shots):
for _ in range(self._shots):
self._quantum_state = np.zeros(1 << self._number_of_qubits,
dtype=complex)
self._quantum_state[0] = 1
@ -377,7 +389,7 @@ class QasmSimulator(BaseBackend):
counts, cl_reg_index, cl_reg_nbits)}
if self._shots == 1:
data['quantum_state'] = self._quantum_state
data['classical_state'] = self._classical_state,
data['classical_state'] = self._classical_state
return {'data': data, 'status': 'DONE'}
def _format_result(self, counts, cl_reg_index, cl_reg_nbits):
@ -387,9 +399,11 @@ class QasmSimulator(BaseBackend):
at register divisions.
Args:
counts : dictionary of counts e.g. {'1111': 1000, '0000':5}
counts (dict): dictionary of counts e.g. {'1111': 1000, '0000':5}
cl_reg_index (list): starting bit index of classical register
cl_reg_nbits (list): total amount of bits in classical register
Returns:
spaces inserted into dictionary keys at register boundries.
dict: spaces inserted into dictionary keys at register boundaries.
"""
fcounts = {}
for key, value in counts.items():

View File

@ -1,3 +1,19 @@
# -*- coding: utf-8 -*-
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# 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
#
# http://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.
# =============================================================================
"""QeRemote module
This module is used for connecting to the Quantum Experience.
@ -29,6 +45,7 @@ class QeRemote(BaseBackend):
Args:
configuration (dict, optional): configuration of backend
"""
super(QeRemote, self).__init__(configuration)
self._configuration = configuration
self._configuration['local'] = False
@ -39,7 +56,7 @@ class QeRemote(BaseBackend):
q_job (QuantumJob): job to run
Returns:
Result object.
Result: Result object.
Raises:
ResultError: if the api put 'error' in its output
@ -62,7 +79,7 @@ class QeRemote(BaseBackend):
seed0 = qobj['circuits'][0]['config']['seed']
hpc = None
if (qobj['config']['backend'] == 'ibmqx_hpc_qasm_simulator' and
'hpc' in qobj['config']):
'hpc' in qobj['config']):
try:
# Use CamelCase when passing the hpc parameters to the API.
hpc = {
@ -71,7 +88,7 @@ class QeRemote(BaseBackend):
'ompNumThreads':
qobj['config']['hpc']['omp_num_threads']
}
except:
except (KeyError, TypeError):
hpc = None
output = self._api.run_job(api_jobs, qobj['config']['backend'],
@ -107,7 +124,7 @@ def _wait_for_job(jobid, api, wait=5, timeout=60):
timeout (int): is how long we wait before failing, in seconds
Returns:
A list of results that correspond to the jobids.
list: A list of results that correspond to the jobids.
Raises:
QISKitError: job didn't return status or reported error in status

View File

@ -23,11 +23,13 @@ Author: Juan Gomez
from qiskit import QISKitError
class SimulatorError(QISKitError):
"""Base class for errors raised by simulators."""
def __init__(self, *message):
"""Set the error message."""
super(SimulatorError, self).__init__(*message)
self.message = ' '.join(message)
def __str__(self):

View File

@ -31,6 +31,8 @@ Functions
"""
import numpy as np
from qiskit import QISKitError
def index1(b, i, k):
"""Magic index1 function.
@ -58,7 +60,7 @@ def index2(b1, i1, b2, i2, k):
Takes a bitstring k and inserts bits b1 as the i1th bit
and b2 as the i2th bit
"""
assert(i1 != i2)
assert i1 != i2
if i1 > i2:
# insert as (i1-1)th bit, will be shifted left 1 by next line
@ -77,13 +79,16 @@ def enlarge_single_opt(opt, qubit, number_of_qubits):
It is exponential in the number of qubits.
Args:
opt: the single-qubit opt.
qubit: the qubit to apply it on counts from 0 and order
opt (array): the single-qubit opt.
qubit (int): the qubit to apply it on counts from 0 and order
is q_{n-1} ... otimes q_1 otimes q_0.
number_of_qubits: the number of qubits in the system.
number_of_qubits (int): the number of qubits in the system.
Returns:
array: enlarge single operator to n qubits
"""
temp_1 = np.identity(2**(number_of_qubits-qubit-1), dtype=complex)
temp_2 = np.identity(2**(qubit), dtype=complex)
temp_2 = np.identity(2**qubit, dtype=complex)
enlarge_opt = np.kron(temp_1, np.kron(opt, temp_2))
return enlarge_opt
@ -104,7 +109,9 @@ def enlarge_two_opt(opt, q0, q1, num):
for k in range(2):
for jj in range(2):
for kk in range(2):
enlarge_opt[index2(j, q0, k, q1, i), index2(jj, q0, kk, q1, i)] = opt[j+2*k, jj+2*kk]
enlarge_opt[index2(j, q0, k, q1, i),
index2(jj, q0, kk, q1, i)] = opt[j+2*k,
jj+2*kk]
return enlarge_opt
@ -115,25 +122,29 @@ def single_gate_params(gate, params=None):
gate(str): the single qubit gate name
params(list): the operation parameters op['params']
Returns:
a tuple of U gate parameters (theta, phi, lam)
tuple: a tuple of U gate parameters (theta, phi, lam)
Raises:
QISKitError: if the gate name is not valid
"""
if gate == 'U' or gate == 'u3':
return (params[0], params[1], params[2])
return params[0], params[1], params[2]
elif gate == 'u2':
return (np.pi/2, params[0], params[1])
return np.pi/2, params[0], params[1]
elif gate == 'u1':
return (0, 0, params[0])
return 0, 0, params[0]
elif gate == 'id':
return (0, 0, 0)
return 0, 0, 0
raise QISKitError('Gate is not among the valid types: %s' % gate)
def single_gate_matrix(gate, params=None):
"""Get the matrix for a single qubit.
Args:
gate(str): the single qubit gate name
params(list): the operation parameters op['params']
Returns:
A numpy array representing the matrix
array: A numpy array representing the matrix
"""
# Converting sym to floats improves the performance of the simulator 10x.

View File

@ -57,8 +57,8 @@ Internal circuit_object::
"conditional": // optional -- map
{
"type": , // string
"mask": , // hex string
"val": , // bhex string
"mask": , // hex string
"val": , // bhex string
}
},
]
@ -90,14 +90,14 @@ returned results object::
'state': 'DONE'
}
"""
import uuid
import logging
import uuid
import numpy as np
import json
from ._simulatortools import enlarge_single_opt, enlarge_two_opt, single_gate_matrix
from qiskit._result import Result
from qiskit.backends._basebackend import BaseBackend
from ._simulatortools import enlarge_single_opt, enlarge_two_opt, single_gate_matrix
logger = logging.getLogger(__name__)
@ -111,6 +111,7 @@ class UnitarySimulator(BaseBackend):
def __init__(self, configuration=None):
"""Initial the UnitarySimulator object."""
super(UnitarySimulator, self).__init__(configuration)
if configuration is None:
self._configuration = {'name': 'local_unitary_simulator',
'url': 'https://github.com/IBM/qiskit-sdk-py',
@ -122,6 +123,10 @@ class UnitarySimulator(BaseBackend):
else:
self._configuration = configuration
# Define attributes inside __init__.
self._unitary_state = None
self._number_of_qubits = 0
def _add_unitary_single(self, gate, qubit):
"""Apply the single-qubit gate.
@ -133,7 +138,7 @@ class UnitarySimulator(BaseBackend):
unitaty_add = enlarge_single_opt(gate, qubit, self._number_of_qubits)
self._unitary_state = np.dot(unitaty_add, self._unitary_state)
def _add_unitary_two(self, gate, q0, q1):
def _add_unitary_two(self, gate, q_0, q_1):
"""Apply the two-qubit gate.
gate is the two-qubit gate
@ -141,23 +146,26 @@ class UnitarySimulator(BaseBackend):
q1 is the second qubit (target)
returns a complex numpy array
"""
unitaty_add = enlarge_two_opt(gate, q0, q1, self._number_of_qubits)
unitaty_add = enlarge_two_opt(gate, q_0, q_1, self._number_of_qubits)
self._unitary_state = np.dot(unitaty_add, self._unitary_state)
def run(self, q_job):
"""Run q_job
Args:
q_job (QuantumJob): job to run
q_job (QuantumJob): job to run
Returns:
Result: Result object
"""
# Generating a string id for the job
job_id = str(uuid.uuid4())
qobj = q_job.qobj
result_list = []
for circuit in qobj['circuits']:
result_list.append( self.run_circuit(circuit) )
return Result({'job_id': job_id, 'result': result_list, 'status': 'COMPLETED'},
qobj)
result_list.append(self.run_circuit(circuit))
return Result(
{'job_id': job_id, 'result': result_list, 'status': 'COMPLETED'},
qobj)
def run_circuit(self, circuit):
"""Apply the single-qubit gate."""

View File

@ -1 +1,19 @@
# -*- coding: utf-8 -*-
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# 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
#
# http://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.
# =============================================================================
"""Module for DAG Circuits."""
from ._dagcircuit import DAGCircuit

View File

@ -120,7 +120,7 @@ class DAGCircuit:
self.output_map[(newname, i)] = self.output_map[(regname, i)]
self.output_map.pop((regname, i), None)
# n node d = data
for n, d in self.multi_graph.nodes_iter(data=True):
for _, d in self.multi_graph.nodes_iter(data=True):
if d["type"] == "in" or d["type"] == "out":
if d["name"][0] == regname:
d["name"] = (newname, d["name"][1])
@ -141,7 +141,7 @@ class DAGCircuit:
if d["condition"][0] == regname:
d["condition"] = (newname, d["condition"][1])
# eX = edge, d= data
for e1, e2, d in self.multi_graph.edges_iter(data=True):
for _, _, d in self.multi_graph.edges_iter(data=True):
if d["name"][0] == regname:
d["name"] = (newname, d["name"][1])
@ -269,13 +269,13 @@ class DAGCircuit:
% name)
else:
# "barrier" is a special case
if len(qargs) == 0:
if not qargs:
raise DAGCircuitError("incorrect number of qubits for %s"
% name)
if len(cargs) != 0:
if cargs:
raise DAGCircuitError("incorrect number of bits for %s"
% name)
if len(params) != 0:
if params:
raise DAGCircuitError("incorrect number of parameters for %s"
% name)
@ -337,7 +337,7 @@ class DAGCircuit:
self.multi_graph.node[self.node_counter]["params"] = nparams
self.multi_graph.node[self.node_counter]["condition"] = ncondition
def apply_operation_back(self, name, qargs, cargs=[], params=[],
def apply_operation_back(self, name, qargs, cargs=None, params=None,
condition=None):
"""Apply an operation to the output of the circuit.
@ -347,6 +347,8 @@ class DAGCircuit:
params is a list of symbols that represent numbers
condition is either None or a tuple (string,int) giving (creg,value)
"""
cargs = cargs or []
params = params or []
all_cbits = self._bits_in_condition(condition)
all_cbits.extend(cargs)
@ -359,7 +361,7 @@ class DAGCircuit:
# will return Python expressions. To get the correct
# OpenQASM expression, we need to replace "**" with "^".
node_params = list(map(lambda x: x.replace("**", "^"),
map(str, params)))
map(str, params)))
self._add_op_node(name, qargs, cargs, node_params,
condition)
# Add new in-edges from predecessors of the output nodes to the
@ -374,7 +376,7 @@ class DAGCircuit:
self.multi_graph.add_edge(
self.node_counter, self.output_map[q], name=q)
def apply_operation_front(self, name, qargs, cargs=[], params=[],
def apply_operation_front(self, name, qargs, cargs=None, params=None,
condition=None):
"""Apply an operation to the input of the circuit.
@ -384,6 +386,8 @@ class DAGCircuit:
params is a list of strings that represent floats
condition is either None or a tuple (string,int) giving (creg,value)
"""
cargs = cargs or []
params = params or []
all_cbits = self._bits_in_condition(condition)
all_cbits.extend(cargs)
@ -396,8 +400,8 @@ class DAGCircuit:
# will return Python expressions. To get the correct
# OpenQASM expression, we need to replace "**" with "^".
node_params = list(map(lambda x: x.replace("**", "^"),
map(str, params)))
self._add_op_node(name, qargs, cargs, node_params,
map(str, params)))
self._add_op_node(name, qargs, cargs, node_params,
condition)
# Add new out-edges to successors of the input nodes from the
# operation node while deleting the old out-edges of the input nodes
@ -543,7 +547,7 @@ class DAGCircuit:
n_condition = (wire_map.get(bit0, bit0)[0], condition[1])
return n_condition
def compose_back(self, input_circuit, wire_map={}):
def compose_back(self, input_circuit, wire_map=None):
"""Apply the input circuit to the output of this circuit.
The two bases must be "compatible" or an exception occurs.
@ -551,6 +555,7 @@ class DAGCircuit:
to a subset of output qubits of this circuit.
wire_map[input_qubit_to_input_circuit] = output_qubit_of_self
"""
wire_map = wire_map or {}
union_basis = self._make_union_basis(input_circuit)
union_gates = self._make_union_gates(input_circuit)
@ -601,7 +606,7 @@ class DAGCircuit:
else:
assert False, "bad node type %s" % nd["type"]
def compose_front(self, input_circuit, wire_map={}):
def compose_front(self, input_circuit, wire_map=None):
"""Apply the input circuit to the input of this circuit.
The two bases must be "compatible" or an exception occurs.
@ -609,6 +614,7 @@ class DAGCircuit:
to a subset of input qubits of
this circuit.
"""
wire_map = wire_map or {}
union_basis = self._make_union_basis(input_circuit)
union_gates = self._make_union_gates(input_circuit)
@ -770,7 +776,7 @@ class DAGCircuit:
if nd["condition"] is not None:
out += "if(%s==%d) " \
% (nd["condition"][0], nd["condition"][1])
if len(nd["cargs"]) == 0:
if not nd["cargs"]:
nm = nd["name"]
if aliases:
qarglist = map(lambda x: aliases[x], nd["qargs"])
@ -778,7 +784,7 @@ class DAGCircuit:
qarglist = nd["qargs"]
qarg = ",".join(map(lambda x: "%s[%d]" % (x[0], x[1]),
qarglist))
if len(nd["params"]) > 0:
if nd["params"]:
if eval_symbols:
param = ",".join(map(lambda x: str(sympy.N(x)),
nd["params"]))
@ -791,7 +797,7 @@ class DAGCircuit:
if nd["name"] == "measure":
assert len(nd["cargs"]) == 1 and \
len(nd["qargs"]) == 1 and \
len(nd["params"]) == 0, "bad node data"
not nd["params"], "bad node data"
qname = nd["qargs"][0][0]
qindex = nd["qargs"][0][1]
if aliases:
@ -866,15 +872,16 @@ class DAGCircuit:
# Otherwise, use the corresponding output nodes of self
# and compute the predecessor.
full_succ_map[w] = self.output_map[w]
full_pred_map[w] = self.multi_graph.predecessors(self.output_map[w])[
0]
full_pred_map[w] = self.multi_graph.predecessors(
self.output_map[w])[0]
assert len(self.multi_graph.predecessors(self.output_map[w])) == 1,\
"too many predecessors for (%s,%d) output node" % (
w[0], w[1])
return full_pred_map, full_succ_map
def substitute_circuit_all(self, name, input_circuit, wires=[]):
def substitute_circuit_all(self, name, input_circuit, wires=None):
"""Replace every occurrence of named operation with input_circuit."""
wires = wires or None
if name not in self.basis:
raise DAGCircuitError("%s is not in the list of basis operations"
% name)
@ -930,10 +937,8 @@ class DAGCircuit:
# Insert a new node
condition = self._map_condition(wire_map,
md["condition"])
m_qargs = list(map(lambda x: wire_map.get(x, x),
md["qargs"]))
m_cargs = list(map(lambda x: wire_map.get(x, x),
md["cargs"]))
m_qargs = [wire_map.get(x, x) for x in md["qargs0"]]
m_cargs = [wire_map.get(x, x) for x in md["cargs0"]]
self._add_op_node(md["name"], m_qargs, m_cargs,
md["params"], condition)
# Add edges from predecessor nodes to new node
@ -947,7 +952,7 @@ class DAGCircuit:
full_pred_map[q] = copy.copy(self.node_counter)
# Connect all predecessors and successors, and remove
# residual edges between input and output nodes
for w in full_pred_map.keys():
for w in full_pred_map:
self.multi_graph.add_edge(full_pred_map[w], full_succ_map[w],
name=w)
o_pred = self.multi_graph.predecessors(
@ -955,19 +960,19 @@ class DAGCircuit:
if len(o_pred) > 1:
assert len(o_pred) == 2, \
"expected 2 predecessors here"
p = list(filter(lambda x: x != full_pred_map[w],
o_pred))
p = [x for x in o_pred if x != full_pred_map[w]]
assert len(p) == 1, \
"expected 1 predecessor to pass filter"
self.multi_graph.remove_edge(
p[0], self.output_map[w])
def substitute_circuit_one(self, node, input_circuit, wires=[]):
def substitute_circuit_one(self, node, input_circuit, wires=None):
"""Replace one node with input_circuit.
node is a reference to a node of self.multi_graph of type "op"
input_circuit is a DAGCircuit
"""
wires = wires or None
nd = self.multi_graph.node[node]
# TODO: reuse common code in substitute_circuit_one and _all
@ -1041,13 +1046,13 @@ class DAGCircuit:
full_pred_map[q] = copy.copy(self.node_counter)
# Connect all predecessors and successors, and remove
# residual edges between input and output nodes
for w in full_pred_map.keys():
for w in full_pred_map:
self.multi_graph.add_edge(
full_pred_map[w], full_succ_map[w], name=w)
o_pred = self.multi_graph.predecessors(self.output_map[w])
if len(o_pred) > 1:
assert len(o_pred) == 2, "expected 2 predecessors here"
p = list(filter(lambda x: x != full_pred_map[w], o_pred))
p = [x for x in o_pred if x != full_pred_map[w]]
assert len(p) == 1, "expected 1 predecessor to pass filter"
self.multi_graph.remove_edge(p[0], self.output_map[w])
@ -1154,9 +1159,9 @@ class DAGCircuit:
wires_loop = list(wires_with_ops_remaining)
emit = False
for w in wires_loop:
oe = list(filter(lambda x: x[2]["name"] == w,
self.multi_graph.out_edges(nbunch=[node_map[w]],
data=True)))
oe = [x for x in self.multi_graph.out_edges(nbunch=[node_map[w]],
data=True) if
x[2]["name"] == w]
assert len(oe) == 1, "should only be one out-edge per (qu)bit"
nxt_nd_idx = oe[0][1]
nxt_nd = self.multi_graph.node[nxt_nd_idx]
@ -1226,7 +1231,7 @@ class DAGCircuit:
ca = copy.copy(nxt_nd["cargs"])
pa = copy.copy(nxt_nd["params"])
co = copy.copy(nxt_nd["condition"])
cob = self._bits_in_condition(co)
_ = self._bits_in_condition(co)
# Add node to new_layer
new_layer.apply_operation_back(nxt_nd["name"],
qa, ca, pa, co)

View File

@ -20,11 +20,13 @@ Exception for errors raised by the DAGCircuit object.
"""
from qiskit import QISKitError
class DAGCircuitError(QISKitError):
"""Base class for errors raised by the DAGCircuit object."""
def __init__(self, *msg):
"""Set the error message."""
super(DAGCircuitError, self).__init__(*msg)
self.msg = ' '.join(msg)
def __str__(self):

View File

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# 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
#
# http://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.
# =============================================================================

View File

@ -26,6 +26,7 @@ class ExtensionError(QISKitError):
def __init__(self, *message):
"""Set the error message."""
super(ExtensionError, self).__init__(*message)
self.message = ' '.join(message)
def __str__(self):

View File

@ -1 +1,19 @@
# -*- coding: utf-8 -*-
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# 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
#
# http://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.
# =============================================================================
"""Initialize qubit registers to desired arbitrary state."""
from ._initializer import InitializeGate

View File

@ -115,9 +115,9 @@ class InitializeGate(CompositeGate):
for i in range(self.num_qubits):
# work out which rotations must be done to disentangle the LSB
# qubit (we peel away one qubit at a time)
remaining_param, \
thetas, \
phis = InitializeGate._rotations_to_disentangle(remaining_param)
(remaining_param,
thetas,
phis) = InitializeGate._rotations_to_disentangle(remaining_param)
# perform the required rotations to decouple the LSB qubit (so that
# it can be "factored" out, leaving a
@ -151,10 +151,10 @@ class InitializeGate(CompositeGate):
# (imagine a qubit state signified by the amplitudes at index 2*i
# and 2*(i+1), corresponding to the select qubits of the
# multiplexor being in state |i>)
remains,\
add_theta,\
add_phi = InitializeGate._bloch_angles(
local_param[2*i : 2*(i + 1)])
(remains,
add_theta,
add_phi) = InitializeGate._bloch_angles(
local_param[2*i: 2*(i + 1)])
remaining_vector.append(remains)

View File

@ -1,3 +1,21 @@
# -*- coding: utf-8 -*-
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# 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
#
# http://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.
# =============================================================================
"""Standard gates."""
from .barrier import barrier
from .ccx import ccx
from .cswap import cswap

View File

@ -23,6 +23,7 @@ from qiskit import QuantumCircuit
from qiskit import CompositeGate
from qiskit import QuantumRegister
from qiskit.extensions._extensionerror import ExtensionError
from qiskit.extensions.standard import header # pylint: disable=unused-import
class Barrier(Instruction):
@ -57,12 +58,12 @@ class Barrier(Instruction):
def barrier(self, *tuples):
"""Apply barrier to tuples (reg, idx)."""
tuples = list(tuples)
if len(tuples) == 0: # TODO: implement this for all single qubit gates
if not tuples: # TODO: implement this for all single qubit gates
if isinstance(self, QuantumCircuit):
for register in self.regs.values():
if isinstance(register, QuantumRegister):
tuples.append(register)
if len(tuples) == 0:
if not tuples:
raise ExtensionError("no arguments passed")
qubits = []
for tuple_element in tuples:

View File

@ -18,10 +18,10 @@
"""
Toffoli gate. Controlled-Controlled-X.
"""
from qiskit import QuantumCircuit
from qiskit import Gate
from qiskit import CompositeGate
from qiskit.extensions.standard import header
from qiskit import Gate
from qiskit import QuantumCircuit
from qiskit.extensions.standard import header # pylint: disable=unused-import
class ToffoliGate(Gate):

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -18,12 +19,13 @@
"""
controlled-H gate.
"""
from qiskit import QuantumCircuit
from qiskit import Gate
from qiskit import CompositeGate
from qiskit.extensions.standard import header
from qiskit._quantumregister import QuantumRegister
from qiskit import Gate
from qiskit import QuantumCircuit
from qiskit._instructionset import InstructionSet
from qiskit._quantumregister import QuantumRegister
from qiskit.extensions.standard import header # pylint: disable=unused-import
class CHGate(Gate):
"""controlled-H gate."""
@ -57,11 +59,11 @@ def ch(self, ctl, tgt):
for i in range(ctl.size):
instructions.add(self.ch((ctl, i), (tgt, i)))
return instructions
else:
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(CHGate(ctl, tgt, self))
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(CHGate(ctl, tgt, self))
QuantumCircuit.ch = ch

View File

@ -18,12 +18,13 @@
"""
controlled-rz gate.
"""
from qiskit import QuantumCircuit
from qiskit import Gate
from qiskit import CompositeGate
from qiskit.extensions.standard import header
from qiskit._quantumregister import QuantumRegister
from qiskit import Gate
from qiskit import QuantumCircuit
from qiskit._instructionset import InstructionSet
from qiskit._quantumregister import QuantumRegister
from qiskit.extensions.standard import header # pylint: disable=unused-import
class CrzGate(Gate):
"""controlled-rz gate."""
@ -38,7 +39,7 @@ class CrzGate(Gate):
tgt = self.arg[1]
theta = self.param[0]
return self._qasmif("crz(%s) %s[%d],%s[%d];" % (theta, ctl[0].name, ctl[1],
tgt[0].name, tgt[1]))
tgt[0].name, tgt[1]))
def inverse(self):
"""Invert this gate."""
@ -59,11 +60,11 @@ def crz(self, theta, ctl, tgt):
for i in range(ctl.size):
instructions.add(self.crz(theta, (ctl, i), (tgt, i)))
return instructions
else:
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(CrzGate(theta, ctl, tgt, self))
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(CrzGate(theta, ctl, tgt, self))
QuantumCircuit.crz = crz

View File

@ -18,10 +18,9 @@
"""
Fredkin gate. Controlled-SWAP.
"""
from qiskit import QuantumCircuit
from qiskit import CompositeGate
from qiskit.extensions.standard import header
from qiskit.extensions.standard import cx, ccx
from qiskit import QuantumCircuit
from qiskit.extensions.standard import header # pylint: disable=unused-import
class FredkinGate(CompositeGate):

View File

@ -18,12 +18,12 @@
"""
controlled-u1 gate.
"""
from qiskit import QuantumCircuit
from qiskit import Gate
from qiskit import CompositeGate
from qiskit.extensions.standard import header
from qiskit._quantumregister import QuantumRegister
from qiskit import Gate
from qiskit import QuantumCircuit
from qiskit._instructionset import InstructionSet
from qiskit._quantumregister import QuantumRegister
from qiskit.extensions.standard import header # pylint: disable=unused-import
class Cu1Gate(Gate):
@ -39,7 +39,7 @@ class Cu1Gate(Gate):
tgt = self.arg[1]
theta = self.param[0]
return self._qasmif("cu1(%s) %s[%d],%s[%d];" % (theta, ctl[0].name, ctl[1],
tgt[0].name, tgt[1]))
tgt[0].name, tgt[1]))
def inverse(self):
"""Invert this gate."""
@ -60,11 +60,11 @@ def cu1(self, theta, ctl, tgt):
for i in range(ctl.size):
instructions.add(self.cu1(theta, (ctl, i), (tgt, i)))
return instructions
else:
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(Cu1Gate(theta, ctl, tgt, self))
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(Cu1Gate(theta, ctl, tgt, self))
QuantumCircuit.cu1 = cu1

View File

@ -18,12 +18,12 @@
"""
controlled-u3 gate.
"""
from qiskit import QuantumCircuit
from qiskit import Gate
from qiskit import CompositeGate
from qiskit.extensions.standard import header
from qiskit._quantumregister import QuantumRegister
from qiskit import Gate
from qiskit import QuantumCircuit
from qiskit._instructionset import InstructionSet
from qiskit._quantumregister import QuantumRegister
from qiskit.extensions.standard import header # pylint: disable=unused-import
class Cu3Gate(Gate):
@ -41,8 +41,8 @@ class Cu3Gate(Gate):
phi = self.param[1]
lam = self.param[2]
return self._qasmif("cu3(%s,%s,%s) %s[%d],%s[%d];" % (theta, phi, lam,
ctl[0].name, ctl[1],
tgt[0].name, tgt[1]))
ctl[0].name, ctl[1],
tgt[0].name, tgt[1]))
def inverse(self):
"""Invert this gate."""
@ -54,7 +54,8 @@ class Cu3Gate(Gate):
def reapply(self, circ):
"""Reapply this gate to corresponding qubits in circ."""
self._modifiers(circ.cu3(self.param[0], self.param[1], self.param[2], self.arg[0], self.arg[1]))
self._modifiers(circ.cu3(self.param[0], self.param[1],
self.param[2], self.arg[0], self.arg[1]))
def cu3(self, theta, phi, lam, ctl, tgt):
@ -66,11 +67,11 @@ def cu3(self, theta, phi, lam, ctl, tgt):
for i in range(ctl.size):
instructions.add(self.cu3(theta, phi, lam, (ctl, i), (tgt, i)))
return instructions
else:
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(Cu3Gate(theta, phi, lam, ctl, tgt, self))
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(Cu3Gate(theta, phi, lam, ctl, tgt, self))
QuantumCircuit.cu3 = cu3

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -18,12 +19,12 @@
"""
controlled-NOT gate.
"""
from qiskit import QuantumCircuit
from qiskit import Gate
from qiskit import CompositeGate
from qiskit.extensions.standard import header
from qiskit._quantumregister import QuantumRegister
from qiskit import Gate
from qiskit import QuantumCircuit
from qiskit._instructionset import InstructionSet
from qiskit._quantumregister import QuantumRegister
from qiskit.extensions.standard import header # pylint: disable=unused-import
class CnotGate(Gate):
@ -58,11 +59,11 @@ def cx(self, ctl, tgt):
for i in range(ctl.size):
instructions.add(self.cx((ctl, i), (tgt, i)))
return instructions
else:
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(CnotGate(ctl, tgt, self))
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(CnotGate(ctl, tgt, self))
QuantumCircuit.cx = cx

View File

@ -18,10 +18,10 @@
"""
Fundamental controlled-NOT gate.
"""
from qiskit import Instruction
from qiskit import CompositeGate
from qiskit import Gate
from qiskit import QuantumCircuit
from qiskit import CompositeGate
from qiskit.extensions.standard import header # pylint: disable=unused-import
class CXBase(Gate):

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -18,12 +19,13 @@
"""
controlled-Y gate.
"""
from qiskit import QuantumCircuit
from qiskit import Gate
from qiskit import CompositeGate
from qiskit.extensions.standard import header
from qiskit._quantumregister import QuantumRegister
from qiskit import Gate
from qiskit import QuantumCircuit
from qiskit._instructionset import InstructionSet
from qiskit._quantumregister import QuantumRegister
from qiskit.extensions.standard import header # pylint: disable=unused-import
class CyGate(Gate):
"""controlled-Y gate."""
@ -57,11 +59,11 @@ def cy(self, ctl, tgt):
for i in range(ctl.size):
instructions.add(self.cy((ctl, i), (tgt, i)))
return instructions
else:
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(CyGate(ctl, tgt, self))
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(CyGate(ctl, tgt, self))
QuantumCircuit.cy = cy

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -17,12 +18,13 @@
"""
controlled-Phase gate.
"""
from qiskit import QuantumCircuit
from qiskit import Gate
from qiskit import CompositeGate
from qiskit.extensions.standard import header
from qiskit._quantumregister import QuantumRegister
from qiskit import Gate
from qiskit import QuantumCircuit
from qiskit._instructionset import InstructionSet
from qiskit._quantumregister import QuantumRegister
from qiskit.extensions.standard import header # pylint: disable=unused-import
class CzGate(Gate):
"""controlled-Z gate."""
@ -56,11 +58,10 @@ def cz(self, ctl, tgt):
for i in range(ctl.size):
instructions.add(self.cz((ctl, i), (tgt, i)))
return instructions
else:
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(CzGate(ctl, tgt, self))
self._check_qubit(ctl)
self._check_qubit(tgt)
self._check_dups([ctl, tgt])
return self._attach(CzGate(ctl, tgt, self))
QuantumCircuit.cz = cz

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -14,17 +15,20 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# =============================================================================
"""Gates tools."""
from qiskit import QuantumRegister
from qiskit import InstructionSet
from qiskit import QuantumRegister
from qiskit.extensions.standard import header # pylint: disable=unused-import
def attach_gate(element, quantum_register, gate, gate_class):
"""Attach a gate."""
if isinstance(quantum_register, QuantumRegister):
gs = InstructionSet()
for register in range(quantum_register.size):
for _ in range(quantum_register.size):
gs.add(gate)
return gs
else:
element._check_qubit(quantum_register)
return element._attach(gate_class)
element._check_qubit(quantum_register)
return element._attach(gate_class)

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -18,12 +19,12 @@
"""
Hadamard gate.
"""
from qiskit import CompositeGate
from qiskit import Gate
from qiskit import InstructionSet
from qiskit import QuantumCircuit
from qiskit import QuantumRegister
from qiskit import Gate
from qiskit import CompositeGate
from qiskit import InstructionSet
from qiskit.extensions.standard import header
from qiskit.extensions.standard import header # pylint: disable=unused-import
class HGate(Gate):
@ -54,9 +55,9 @@ def h(self, q):
for j in range(q.size):
gs.add(self.h((q, j)))
return gs
else:
self._check_qubit(q)
return self._attach(HGate(q, self))
self._check_qubit(q)
return self._attach(HGate(q, self))
QuantumCircuit.h = h

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -18,12 +19,12 @@
"""
Identity gate.
"""
from qiskit import CompositeGate
from qiskit import Gate
from qiskit import InstructionSet
from qiskit import QuantumCircuit
from qiskit import QuantumRegister
from qiskit import Gate
from qiskit import CompositeGate
from qiskit import InstructionSet
from qiskit.extensions.standard import header
from qiskit.extensions.standard import header # pylint: disable=unused-import
class IdGate(Gate):
@ -54,9 +55,9 @@ def iden(self, q):
for j in range(q.size):
gs.add(self.iden((q, j)))
return gs
else:
self._check_qubit(q)
return self._attach(IdGate(q, self))
self._check_qubit(q)
return self._attach(IdGate(q, self))
QuantumCircuit.iden = iden

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -18,12 +19,12 @@
"""
Rotation around the x-axis.
"""
from qiskit import QuantumRegister
from qiskit import QuantumCircuit
from qiskit import CompositeGate
from qiskit import Gate
from qiskit import InstructionSet
from qiskit import CompositeGate
from qiskit.extensions.standard import header
from qiskit import QuantumCircuit
from qiskit import QuantumRegister
from qiskit.extensions.standard import header # pylint: disable=unused-import
class RXGate(Gate):
@ -38,7 +39,7 @@ class RXGate(Gate):
qubit = self.arg[0]
theta = self.param[0]
return self._qasmif("rx(%s) %s[%d];" % (theta, qubit[0].name,
qubit[1]))
qubit[1]))
def inverse(self):
"""Invert this gate.
@ -60,9 +61,9 @@ def rx(self, theta, q):
for j in range(q.sz):
gs.add(self.rx(theta, (q, j)))
return gs
else:
self._check_qubit(q)
return self._attach(RXGate(theta, q, self))
self._check_qubit(q)
return self._attach(RXGate(theta, q, self))
QuantumCircuit.rx = rx

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -18,12 +19,13 @@
"""
Rotation around the y-axis.
"""
from qiskit import QuantumRegister
from qiskit import QuantumCircuit
from qiskit import CompositeGate
from qiskit import Gate
from qiskit import InstructionSet
from qiskit import CompositeGate
from qiskit.extensions.standard import header
from qiskit import QuantumCircuit
from qiskit import QuantumRegister
from qiskit.extensions.standard import header # pylint: disable=unused-import
class RYGate(Gate):
"""rotation around the y-axis."""
@ -37,7 +39,7 @@ class RYGate(Gate):
qubit = self.arg[0]
theta = self.param[0]
return self._qasmif("ry(%s) %s[%d];" % (theta, qubit[0].name,
qubit[1]))
qubit[1]))
def inverse(self):
"""Invert this gate.
@ -59,9 +61,9 @@ def ry(self, theta, q):
for j in range(q.sz):
gs.add(self.ry(theta, (q, j)))
return gs
else:
self._check_qubit(q)
return self._attach(RYGate(theta, q, self))
self._check_qubit(q)
return self._attach(RYGate(theta, q, self))
QuantumCircuit.ry = ry

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -18,12 +19,12 @@
"""
Rotation around the z-axis.
"""
from qiskit import QuantumRegister
from qiskit import QuantumCircuit
from qiskit import CompositeGate
from qiskit import Gate
from qiskit import InstructionSet
from qiskit import CompositeGate
from qiskit.extensions.standard import header
from qiskit import QuantumCircuit
from qiskit import QuantumRegister
from qiskit.extensions.standard import header # pylint: disable=unused-import
class RZGate(Gate):
@ -37,8 +38,7 @@ class RZGate(Gate):
"""Return OPENQASM string."""
qubit = self.arg[0]
phi = self.param[0]
return self._qasmif("rz(%s) %s[%d];" % (phi, qubit[0].name,
qubit[1]))
return self._qasmif("rz(%s) %s[%d];" % (phi, qubit[0].name, qubit[1]))
def inverse(self):
"""Invert this gate.
@ -60,9 +60,9 @@ def rz(self, phi, q):
for j in range(q.sz):
gs.add(self.rx(phi, (q, j)))
return gs
else:
self._check_qubit(q)
return self._attach(RZGate(phi, q, self))
self._check_qubit(q)
return self._attach(RZGate(phi, q, self))
QuantumCircuit.rz = rz

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -18,13 +19,12 @@
"""
S=diag(1,i) Clifford phase gate or its inverse.
"""
from qiskit import QuantumRegister
from qiskit import QuantumCircuit
from qiskit import CompositeGate
from qiskit import InstructionSet
from qiskit import QuantumCircuit
from qiskit import QuantumRegister
from qiskit.qasm import pi
from qiskit.extensions.standard import header
from qiskit.extensions.standard import u1
from qiskit.extensions.standard import header # pylint: disable=unused-import
class SGate(CompositeGate):
@ -45,8 +45,8 @@ class SGate(CompositeGate):
phi = self.data[0].param[0]
if phi > 0:
return self.data[0]._qasmif("s %s[%d];" % (qubit[0].name, qubit[1]))
else:
return self.data[0]._qasmif("sdg %s[%d];" % (qubit[0].name, qubit[1]))
return self.data[0]._qasmif("sdg %s[%d];" % (qubit[0].name, qubit[1]))
def s(self, q):
@ -56,9 +56,9 @@ def s(self, q):
for j in range(q.size):
gs.add(self.s((q, j)))
return gs
else:
self._check_qubit(q)
return self._attach(SGate(q, self))
self._check_qubit(q)
return self._attach(SGate(q, self))
def sdg(self, q):

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -18,10 +19,10 @@
"""
SWAP gate.
"""
from qiskit import QuantumCircuit
from qiskit import Gate
from qiskit import CompositeGate
from qiskit.extensions.standard import header
from qiskit import Gate
from qiskit import QuantumCircuit
from qiskit.extensions.standard import header # pylint: disable=unused-import
class SwapGate(Gate):

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -18,13 +19,12 @@
"""
T=sqrt(S) phase gate or its inverse.
"""
from qiskit import QuantumRegister
from qiskit import QuantumCircuit
from qiskit import CompositeGate
from qiskit import InstructionSet
from qiskit import QuantumCircuit
from qiskit import QuantumRegister
from qiskit.qasm import pi
from qiskit.extensions.standard import header
from qiskit.extensions.standard import u1
from qiskit.extensions.standard import header # pylint: disable=unused-import
class TGate(CompositeGate):
@ -45,8 +45,8 @@ class TGate(CompositeGate):
phi = self.data[0].param[0]
if phi > 0:
return self.data[0]._qasmif("t %s[%d];" % (qubit[0].name, qubit[1]))
else:
return self.data[0]._qasmif("tdg %s[%d];" % (qubit[0].name, qubit[1]))
return self.data[0]._qasmif("tdg %s[%d];" % (qubit[0].name, qubit[1]))
def t(self, q):
@ -56,9 +56,9 @@ def t(self, q):
for j in range(q.size):
gs.add(self.t((q, j)))
return gs
else:
self._check_qubit(q)
return self._attach(TGate(q, self))
self._check_qubit(q)
return self._attach(TGate(q, self))
def tdg(self, q):

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -18,12 +19,12 @@
"""
Diagonal single qubit gate.
"""
from qiskit import QuantumRegister
from qiskit import QuantumCircuit
from qiskit import CompositeGate
from qiskit import Gate
from qiskit import InstructionSet
from qiskit import CompositeGate
from qiskit.extensions.standard import header
from qiskit import QuantumCircuit
from qiskit import QuantumRegister
from qiskit.extensions.standard import header # pylint: disable=unused-import
class U1Gate(Gate):
@ -37,8 +38,8 @@ class U1Gate(Gate):
"""Return OPENQASM string."""
qubit = self.arg[0]
theta = self.param[0]
return self._qasmif("u1(%s) %s[%d];" % (theta, qubit[0].name,
qubit[1]))
return self._qasmif("u1(%s) %s[%d];" % (
theta, qubit[0].name, qubit[1]))
def inverse(self):
"""Invert this gate."""
@ -57,9 +58,9 @@ def u1(self, theta, q):
for j in range(q.size):
gs.add(self.u1(theta, (q, j)))
return gs
else:
self._check_qubit(q)
return self._attach(U1Gate(theta, q, self))
self._check_qubit(q)
return self._attach(U1Gate(theta, q, self))
QuantumCircuit.u1 = u1

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -18,13 +19,13 @@
"""
One-pulse single-qubit gate.
"""
from qiskit import QuantumRegister
from qiskit import QuantumCircuit
from qiskit import CompositeGate
from qiskit import Gate
from qiskit import InstructionSet
from qiskit import CompositeGate
from qiskit import QuantumCircuit
from qiskit import QuantumRegister
from qiskit.qasm import pi
from qiskit.extensions.standard import header
from qiskit.extensions.standard import header # pylint: disable=unused-import
class U2Gate(Gate):
@ -40,8 +41,8 @@ class U2Gate(Gate):
phi = self.param[0]
lam = self.param[1]
return self._qasmif("u2(%s,%s) %s[%d];" % (phi, lam,
qubit[0].name,
qubit[1]))
qubit[0].name,
qubit[1]))
def inverse(self):
"""Invert this gate.
@ -65,9 +66,9 @@ def u2(self, phi, lam, q):
for j in range(q.size):
gs.add(self.u2(phi, lam, (q, j)))
return gs
else:
self._check_qubit(q)
return self._attach(U2Gate(phi, lam, q, self))
self._check_qubit(q)
return self._attach(U2Gate(phi, lam, q, self))
QuantumCircuit.u2 = u2

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -18,12 +19,12 @@
"""
Two-pulse single-qubit gate.
"""
from qiskit import QuantumRegister
from qiskit import QuantumCircuit
from qiskit import CompositeGate
from qiskit import Gate
from qiskit import InstructionSet
from qiskit import CompositeGate
from qiskit.extensions.standard import header
from qiskit import QuantumCircuit
from qiskit import QuantumRegister
from qiskit.extensions.standard import header # pylint: disable=unused-import
class U3Gate(Gate):
@ -40,8 +41,8 @@ class U3Gate(Gate):
phi = self.param[1]
lam = self.param[2]
return self._qasmif("u3(%s,%s,%s) %s[%d];" % (theta, phi, lam,
qubit[0].name,
qubit[1]))
qubit[0].name,
qubit[1]))
def inverse(self):
"""Invert this gate.
@ -67,9 +68,9 @@ def u3(self, theta, phi, lam, q):
for j in range(q.size):
gs.add(self.u3(theta, phi, lam, (q, j)))
return gs
else:
self._check_qubit(q)
return self._attach(U3Gate(theta, phi, lam, q, self))
self._check_qubit(q)
return self._attach(U3Gate(theta, phi, lam, q, self))
QuantumCircuit.u3 = u3

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -18,10 +19,11 @@
"""
Element of SU(2).
"""
from qiskit import Gate
from qiskit.extensions._extensionerror import ExtensionError
from qiskit import QuantumCircuit
from qiskit import CompositeGate
from qiskit import Gate
from qiskit import QuantumCircuit
from qiskit.extensions._extensionerror import ExtensionError
from qiskit.extensions.standard import header # pylint: disable=unused-import
class UBase(Gate):
@ -39,8 +41,8 @@ class UBase(Gate):
phi = self.param[1]
lamb = self.param[2]
qubit = self.arg[0]
return self._qasmif("U(%s,%s,%s) %s[%d];" % (theta, phi,
lamb, qubit[0].name, qubit[1]))
return self._qasmif("U(%s,%s,%s) %s[%d];" % (
theta, phi, lamb, qubit[0].name, qubit[1]))
def inverse(self):
"""Invert this gate.
@ -55,7 +57,7 @@ class UBase(Gate):
def reapply(self, circ):
"""Reapply this gate to corresponding qubits in circ."""
self._modifiers(circ.u_base(self.param,self.arg[0]))
self._modifiers(circ.u_base(self.param, self.arg[0]))
def u_base(self, tpl, q):

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -18,12 +19,12 @@
"""
Pauli X (bit-flip) gate.
"""
from qiskit import QuantumRegister
from qiskit import QuantumCircuit
from qiskit import Gate
from qiskit import CompositeGate
from qiskit import Gate
from qiskit import InstructionSet
from qiskit.extensions.standard import header
from qiskit import QuantumCircuit
from qiskit import QuantumRegister
from qiskit.extensions.standard import header # pylint: disable=unused-import
class XGate(Gate):
@ -54,9 +55,9 @@ def x(self, q):
for j in range(q.size):
gs.add(self.x((q, j)))
return gs
else:
self._check_qubit(q)
return self._attach(XGate(q, self))
self._check_qubit(q)
return self._attach(XGate(q, self))
QuantumCircuit.x = x

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -18,12 +19,12 @@
"""
Pauli Y (bit-phase-flip) gate.
"""
from qiskit import QuantumRegister
from qiskit import QuantumCircuit
from qiskit import Gate
from qiskit import CompositeGate
from qiskit import Gate
from qiskit import InstructionSet
from qiskit.extensions.standard import header
from qiskit import QuantumCircuit
from qiskit import QuantumRegister
from qiskit.extensions.standard import header # pylint: disable=unused-import
class YGate(Gate):
@ -54,9 +55,9 @@ def y(self, quantum_register):
for register in range(quantum_register.size):
intructions.add(self.y((quantum_register, register)))
return intructions
else:
self._check_qubit(quantum_register)
return self._attach(YGate(quantum_register, self))
self._check_qubit(quantum_register)
return self._attach(YGate(quantum_register, self))
QuantumCircuit.y = y

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -18,12 +19,12 @@
"""
Pauli Z (phase-flip) gate.
"""
from qiskit import QuantumRegister
from qiskit import QuantumCircuit
from qiskit import Gate
from qiskit import CompositeGate
from qiskit import Gate
from qiskit import InstructionSet
from qiskit.extensions.standard import header
from qiskit import QuantumCircuit
from qiskit import QuantumRegister
from qiskit.extensions.standard import header # pylint: disable=unused-import
class ZGate(Gate):
@ -54,9 +55,9 @@ def z(self, quantum_register):
for register in range(quantum_register.size):
intructions.add(self.z((quantum_register, register)))
return intructions
else:
self._check_qubit(quantum_register)
return self._attach(ZGate(quantum_register, self))
self._check_qubit(quantum_register)
return self._attach(ZGate(quantum_register, self))
QuantumCircuit.z = z

View File

@ -1,4 +1,23 @@
from ._coupling import Coupling, coupling_dict2list, coupling_list2dict
from ._mapping import swap_mapper, direction_mapper, cx_cancellation, optimize_1q_gates
# -*- coding: utf-8 -*-
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# 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
#
# http://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.
# =============================================================================
"""Utils for mapping."""
from ._compiling import two_qubit_kak, euler_angles_1q
from ._coupling import Coupling, coupling_dict2list, coupling_list2dict
from ._mappererror import MapperError
from ._mapping import swap_mapper, direction_mapper, cx_cancellation, optimize_1q_gates

View File

@ -20,7 +20,7 @@
Methods to assist with compiling tasks.
"""
import math
import scipy
import numpy as np
from scipy.linalg import expm

View File

@ -20,11 +20,13 @@ Exception for errors raised by the Coupling object.
"""
from qiskit import QISKitError
class CouplingError(QISKitError):
"""Base class for errors raised by the coupling graph object."""
def __init__(self, *msg):
"""Set the error message."""
super(CouplingError, self).__init__(*msg)
self.msg = ' '.join(msg)
def __str__(self):

View File

@ -21,11 +21,13 @@ Exception for errors raised by mapper module.
from qiskit import QISKitError
class MapperError(QISKitError):
"""Base class for errors raised by mapper module."""
def __init__(self, *message):
"""Set the error message."""
super(MapperError, self).__init__(*message)
self.message = ' '.join(message)
def __str__(self):

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# pylint: disable=invalid-name, inconsistent-return-statements
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -19,17 +19,19 @@
"""
Layout module to assist with mapping circuit qubits onto physical qubits.
"""
import sys
import copy
import logging
import pprint
import sys
import networkx as nx
import numpy as np
import sympy
from sympy import Number as N
import numpy as np
import networkx as nx
import pprint
from ._mappererror import MapperError
from qiskit.qasm import Qasm
import qiskit.unroll as unroll
from qiskit.qasm import Qasm
from ._mappererror import MapperError
logger = logging.getLogger(__name__)
@ -44,7 +46,8 @@ logger = logging.getLogger(__name__)
# because the initial state is zero. We don't do this.
def layer_permutation(layer_partition, layout, qubit_subset, coupling, trials, seed=None):
def layer_permutation(layer_partition, layout, qubit_subset, coupling, trials,
seed=None):
"""Find a swap circuit that implements a permutation for this layer.
The goal is to swap qubits such that qubits in the same two-qubit gates
@ -96,7 +99,7 @@ def layer_permutation(layer_partition, layout, qubit_subset, coupling, trials, s
if dist == len(gates):
logger.debug("layer_permutation: done already")
logger.debug("layer_permutation: ----- exit -----")
return True, "", 0, layout, len(gates) == 0
return True, "", 0, layout, bool(gates)
# Begin loop over trials of randomized algorithm
n = coupling.size()
@ -203,10 +206,10 @@ def layer_permutation(layer_partition, layout, qubit_subset, coupling, trials, s
logger.debug("layer_permutation: failed!")
logger.debug("layer_permutation: ----- exit -----")
return False, None, None, None, False
else:
logger.debug("layer_permutation: done")
logger.debug("layer_permutation: ----- exit -----")
return True, best_circ, best_d, best_layout, False
logger.debug("layer_permutation: done")
logger.debug("layer_permutation: ----- exit -----")
return True, best_circ, best_d, best_layout, False
def direction_mapper(circuit_graph, coupling_graph):
@ -256,7 +259,7 @@ def direction_mapper(circuit_graph, coupling_graph):
cxedge[1][0], cxedge[1][1])
else:
raise MapperError("circuit incompatible with CouplingGraph: "
"cx on %s", pprint.pformat(cxedge))
"cx on %s" % pprint.pformat(cxedge))
return circuit_graph
@ -317,16 +320,20 @@ def swap_mapper(circuit_graph, coupling_graph,
coupling_graph (CouplingGraph): coupling graph to map onto
initial_layout (dict): dict from qubits of circuit_graph to qubits
of coupling_graph (optional)
basis (str, optional): basis string specifying basis of output
DAGCircuit
basis (str): basis string specifying basis of output DAGCircuit
trials (int): number of trials.
seed (int): initial seed.
Returns:
Returns a DAGCircuit object containing a circuit equivalent to
DAGCircuit: object containing a circuit equivalent to
circuit_graph that respects couplings in coupling_graph, and
a layout dict mapping qubits of circuit_graph into qubits
of coupling_graph. The layout may differ from the initial_layout
if the first layer of gates cannot be executed on the
initial_layout.
Raises:
MapperError: if there was any error during the mapping or with the
parameters.
"""
if circuit_graph.width() > coupling_graph.size():
raise MapperError("Not enough qubits in CouplingGraph")
@ -471,15 +478,16 @@ def test_trig_solution(theta, phi, lamb, xi, theta1, theta2):
http://docs.sympy.org/latest/modules/functions/elementary.html?highlight=max
"""
delta1 = sympy.cos(phi + lamb) * sympy.cos(theta) - \
sympy.cos(xi) * sympy.cos(theta1 + theta2)
sympy.cos(xi) * sympy.cos(theta1 + theta2)
delta2 = sympy.sin(phi + lamb) * sympy.cos(theta) - \
sympy.sin(xi) * sympy.cos(theta1 - theta2)
sympy.sin(xi) * sympy.cos(theta1 - theta2)
delta3 = sympy.cos(phi - lamb) * sympy.sin(theta) - \
sympy.cos(xi) * sympy.sin(theta1 + theta2)
sympy.cos(xi) * sympy.sin(theta1 + theta2)
delta4 = sympy.sin(phi - lamb) * sympy.sin(theta) - \
sympy.sin(xi) * sympy.sin(-theta1 + theta2)
sympy.sin(xi) * sympy.sin(-theta1 + theta2)
[delta1, delta2, delta3, delta4] = map(lambda x: sympy.Abs(x.simplify()), [delta1, delta2, delta3, delta4])
[delta1, delta2, delta3, delta4] = map(lambda x: sympy.Abs(x.simplify()),
[delta1, delta2, delta3, delta4])
return sympy.Max(delta1, delta2, delta3, delta4)
@ -564,6 +572,7 @@ def yzy_to_zyz(xi, theta1, theta2, eps=1e-9):
solutions.append((sympy.acos(sympy.cos(xi) * sympy.cos(theta1 + theta2) /
sympy.cos(sphi + slam + sympy.pi)),
sphi + sympy.pi, slam))
# Select the first solution with the required accuracy
deltas = list(map(lambda x: test_trig_solution(x[0], x[1], x[2],
xi, theta1, theta2),

View File

@ -1,3 +1,23 @@
# -*- coding: utf-8 -*-
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# 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
#
# http://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.
# =============================================================================
"""Tools for QASM."""
from sympy import pi
from ._qasm import Qasm
from ._qasmerror import QasmError
from sympy import pi

View File

@ -1,3 +1,21 @@
# -*- coding: utf-8 -*-
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# 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
#
# http://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.
# =============================================================================
"""QASM nodes."""
from ._barrier import Barrier
from ._binaryop import BinaryOp
from ._binaryoperator import BinaryOperator

View File

@ -18,9 +18,10 @@
"""
Node for an OPENQASM binary operation expression.
"""
from ._node import Node
import sympy
from ._node import Node
class BinaryOp(Node):
"""Node for an OPENQASM binary operation expression.
@ -41,6 +42,7 @@ class BinaryOp(Node):
def latex(self, prec=15, nested_scope=None):
"""Return the corresponding math mode latex string."""
# pylint: disable=unused-argument
# TODO prec ignored
return sympy.latex(self.sym(nested_scope))

View File

@ -54,4 +54,6 @@ class BinaryOperator(Node):
self.value)
def qasm(self, prec=15):
"""Return the QASM representation."""
# pylint: disable=unused-argument
return self.value

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
@ -41,6 +41,7 @@ class External(Node):
def latex(self, prec=15, nested_scope=None):
"""Return the corresponding math mode latex string."""
# pylint: disable=unused-argument
# TODO prec ignored
return sympy.latex(self.sym(nested_scope))

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#

View File

@ -31,6 +31,7 @@ class Id(Node):
def __init__(self, id, line, file):
"""Create the id node."""
# pylint: disable=redefined-builtin
Node.__init__(self, "id", None, None)
self.name = id
self.line = line
@ -46,6 +47,7 @@ class Id(Node):
def qasm(self, prec=15):
"""Return the corresponding OPENQASM string."""
# pylint: disable=unused-argument
return self.name
def latex(self, prec=15, nested_scope=None):
@ -65,19 +67,17 @@ class Id(Node):
def sym(self, nested_scope=None):
"""Return the correspond symbolic number."""
if not nested_scope or self.name not in nested_scope[-1]:
raise NodeException("Expected local parameter name: ",
"name=%s, " % self.name,
"line=%s, " % self.line,
"file=%s" % self.file)
raise NodeException("Expected local parameter name: ",
"name=%s, line=%s, file=%s" % (
self.name, self.line, self.file))
else:
return nested_scope[-1][self.name].sym(nested_scope[0:-1])
def real(self, nested_scope=None):
"""Return the correspond floating point number."""
if not nested_scope or self.name not in nested_scope[-1]:
raise NodeException("Expected local parameter name: ",
"name=%s, " % self.name,
"line=%s, " % self.line,
"file=%s" % self.file)
raise NodeException("Expected local parameter name: ",
"name=%s, line=%s, file=%s" % (
self.name, self.line, self.file))
else:
return nested_scope[-1][self.name].real(nested_scope[0:-1])

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -44,4 +45,5 @@ class IndexedId(Node):
def qasm(self, prec=15):
"""Return the corresponding OPENQASM string."""
# pylint: disable=unused-argument
return self.name + "[%d]" % self.index

View File

@ -18,9 +18,11 @@
"""
Node for an OPENQASM integer.
"""
from ._node import Node
from sympy import N
from ._node import Node
class Int(Node):
"""Node for an OPENQASM integer.
@ -29,6 +31,7 @@ class Int(Node):
def __init__(self, id):
"""Create the integer node."""
# pylint: disable=redefined-builtin
Node.__init__(self, "int", None, None)
self.value = id
@ -39,16 +42,20 @@ class Int(Node):
def qasm(self, prec=15):
"""Return the corresponding OPENQASM string."""
# pylint: disable=unused-argument
return "%d" % self.value
def latex(self, prec=15, nested_scope=None):
"""Return the corresponding math mode latex string."""
# pylint: disable=unused-argument
return "%d" % self.value
def sym(self, nested_scope=None):
"""Return the correspond symbolic number."""
# pylint: disable=unused-argument
return N(self.value)
def real(self, nested_scope=None):
"""Return the correspond floating point number."""
# pylint: disable=unused-argument
return float(self.value)

View File

@ -33,4 +33,5 @@ class Magic(Node):
def qasm(self, prec=15):
"""Return the corresponding OPENQASM string."""
# pylint: disable=unused-argument
return "OPENQASM %.1f;" % self.children[0].value

View File

@ -25,6 +25,7 @@ class Node(object):
def __init__(self, type, children=None, root=None):
"""Construct a new node object."""
# pylint: disable=redefined-builtin
self.type = type
if children:
self.children = children

View File

@ -25,6 +25,7 @@ class NodeException(Exception):
def __init__(self, *msg):
"""Set the error message."""
super(NodeException, self).__init__(*msg)
self.msg = ' '.join(msg)
def __str__(self):

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#

View File

@ -18,9 +18,10 @@
"""
Node for an OPENQASM prefix expression.
"""
from ._node import Node
import sympy
from ._node import Node
class Prefix(Node):
"""Node for an OPENQASM prefix expression.
@ -39,6 +40,7 @@ class Prefix(Node):
def latex(self, prec=15, nested_scope=None):
"""Return the corresponding math mode latex string."""
# pylint: disable=unused-argument
# TODO prec ignored
return sympy.latex(self.sym(nested_scope))

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#

View File

@ -31,6 +31,7 @@ class Real(Node):
def __init__(self, id):
"""Create the real node."""
# pylint: disable=redefined-builtin
Node.__init__(self, "real", None, None)
self.value = id
@ -43,17 +44,20 @@ class Real(Node):
"""Return the corresponding OPENQASM string."""
if self.value == pi:
return "pi"
else:
return ccode(self.value, precision=prec)
return ccode(self.value, precision=prec)
def latex(self, prec=15, nested_scope=None):
"""Return the corresponding math mode latex string."""
# pylint: disable=unused-argument
return latex(self.value)
def sym(self, nested_scope=None):
"""Return the correspond symbolic number."""
# pylint: disable=unused-argument
return self.value
def real(self, nested_scope=None):
"""Return the correspond floating point number."""
# pylint: disable=unused-argument
return float(self.value.evalf())

View File

@ -51,4 +51,6 @@ class UnaryOperator(Node):
self.value)
def qasm(self, prec=15):
"""Return QASM representation."""
# pylint: disable=unused-argument
return self.value

View File

@ -30,8 +30,8 @@ class Qasm(object):
if filename is None and data is None:
raise QasmError("Missing input file and/or data")
if filename is not None and data is not None:
raise QasmError("File and data must not both be"
+ " specified initializing qasm")
raise QasmError("File and data must not both be specified"
"initializing qasm")
self._filename = filename
self._data = data

View File

@ -21,11 +21,13 @@ Exception for errors raised while parsing OPENQASM.
from qiskit import QISKitError
class QasmError(QISKitError):
"""Base class for errors raised while parsing OPENQASM."""
def __init__(self, *msg):
"""Set the error message."""
super(QasmError, self).__init__(*msg)
self.msg = ' '.join(msg)
def __str__(self):

View File

@ -23,11 +23,13 @@ by creating a stack of lexers.
"""
import os
import ply.lex as lex
from ._qasmerror import QasmError
from . import _node as node
from sympy import Number
from . import _node as node
from ._qasmerror import QasmError
CORE_LIBS_PATH = os.path.join(os.path.dirname(__file__), 'libs')
CORE_LIBS = os.listdir(CORE_LIBS_PATH)
@ -38,7 +40,8 @@ class QasmLexer(object):
This is a wrapper around the PLY lexer to support the "include" statement
by creating a stack of lexers.
"""
# pylint: disable=invalid-name
# pylint: disable=invalid-name,missing-docstring,unused-argument
# pylint: disable=attribute-defined-outside-init
def __mklexer__(self, filename):
"""Create a PLY lexer."""
@ -127,37 +130,34 @@ class QasmLexer(object):
def t_INCLUDE(self, t):
'include'
'''
Now eat up the next two tokens which must be
1 - the name of the include file, and
2 - a terminating semicolon
Then push the current lexer onto the stack, create a new one from
the include file, and push it onto the stack.
When we hit eof (the t_eof) rule, we pop.
'''
next = self.lexer.token()
lineno = next.lineno
#
# Now eat up the next two tokens which must be
# 1 - the name of the include file, and
# 2 - a terminating semicolon
#
# Then push the current lexer onto the stack, create a new one from
# the include file, and push it onto the stack.
#
# When we hit eof (the t_eof) rule, we pop.
next_token = self.lexer.token()
lineno = next_token.lineno
# print('NEXT', next, "next.value", next.value, type(next))
if isinstance(next.value, str):
incfile = next.value.strip('"')
if isinstance(next_token.value, str):
incfile = next_token.value.strip('"')
else:
raise QasmError("Invalid include: must be a quoted string.")
if incfile in CORE_LIBS:
incfile = os.path.join(CORE_LIBS_PATH, incfile)
next = self.lexer.token()
if next is None or next.value != ';':
raise QasmError('Invalid syntax, missing ";" at line',
str(lineno))
next_token = self.lexer.token()
if next_token is None or next_token.value != ';':
raise QasmError('Invalid syntax, missing ";" at line', str(lineno))
if not os.path.exists(incfile):
raise QasmError('Include file', incfile,
'cannot be found, line', str(next.lineno),
', file', self.filename)
raise QasmError(
'Include file %s cannot be found, line %s, file %s' %
(incfile, str(next_token.lineno), self.filename))
self.push(incfile)
return self.lexer.token()
@ -191,11 +191,10 @@ class QasmLexer(object):
t.lexer.lineno = self.lineno
def t_eof(self, t):
if len(self.stack) > 0:
if self.stack:
self.pop()
return self.lexer.token()
else:
return None
return None
t_ignore = ' \t\r'

View File

@ -19,20 +19,22 @@
OPENQASM parser.
"""
import os
import sympy
import tempfile
import shutil
import tempfile
import ply.yacc as yacc
import sympy
from ._qasmlexer import QasmLexer
from ._qasmerror import QasmError
from . import _node as node
from ._qasmerror import QasmError
from ._qasmlexer import QasmLexer
class QasmParser(object):
"""OPENQASM Parser."""
# pylint: disable=unused-argument,missing-docstring,invalid-name
def __init__(self, filename):
"""Create the parser."""
if filename is None:
@ -41,10 +43,10 @@ class QasmParser(object):
self.tokens = self.lexer.tokens
self.parse_dir = tempfile.mkdtemp(prefix='qiskit')
self.precedence = (
('left', '+', '-'),
('left', '*', '/'),
('left', 'negative', 'positive'),
('right', '^'))
('left', '+', '-'),
('left', '*', '/'),
('left', 'negative', 'positive'),
('right', '^'))
# For yacc, also, write_tables = Bool and optimize = Bool
self.parser = yacc.yacc(module=self, debug=False,
outputdir=self.parse_dir)
@ -53,7 +55,8 @@ class QasmParser(object):
self.global_symtab = {} # global symtab
self.current_symtab = self.global_symtab # top of symbol stack
self.symbols = [] # symbol stack
self.external_functions = ['sin', 'cos', 'tan', 'exp', 'ln', 'sqrt','acos','atan','asin']
self.external_functions = ['sin', 'cos', 'tan', 'exp', 'ln', 'sqrt',
'acos', 'atan', 'asin']
def __enter__(self):
return self
@ -173,8 +176,9 @@ class QasmParser(object):
if g_sym.type != object_type:
raise QasmError("Type for '" + g_sym.name + "' should be '"
+ object_type + "' but was found to be '" + g_sym.type
+ "'", "line", str(obj.line), "file", obj.file)
+ object_type + "' but was found to be '"
+ g_sym.type + "'", "line", str(obj.line),
"file", obj.file)
if obj.type == 'indexed_id':
bound = g_sym.index
@ -456,8 +460,8 @@ class QasmParser(object):
"""
if len(program) > 2:
if program[2] != ';':
raise QasmError("Missing ';' in qreg or creg declaraton."
+ " Instead received '" + program[2].value + "'")
raise QasmError("Missing ';' in qreg or creg declaration."
" Instead received '" + program[2].value + "'")
program[0] = program[1]
# ----------------------------------------

View File

@ -1,3 +1,21 @@
# -*- coding: utf-8 -*-
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# 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
#
# http://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.
# =============================================================================
"""Unroll QASM and different backends."""
from ._unroller import Unroller
from ._dagbackend import DAGBackend
from ._printerbackend import PrinterBackend

View File

@ -21,11 +21,13 @@ Exception for errors raised by unroller backends.
from qiskit import QISKitError
class BackendError(QISKitError):
"""Base class for errors raised by unroller backends."""
def __init__(self, *message):
"""Set the error message."""
super(BackendError, self).__init__(*message)
self.message = ' '.join(message)
def __str__(self):

View File

@ -18,15 +18,12 @@
"""
Backend for the unroller that produces a QuantumCircuit.
"""
from ._backenderror import BackendError
from ._unrollerbackend import UnrollerBackend
from .._quantumregister import QuantumRegister
from .._classicalregister import ClassicalRegister
from .._quantumcircuit import QuantumCircuit
import sys
sys.path.append("../..")
import qiskit.extensions.standard
from .._quantumregister import QuantumRegister
class CircuitBackend(UnrollerBackend):
@ -40,6 +37,7 @@ class CircuitBackend(UnrollerBackend):
basis is a list of operation name strings.
"""
super(CircuitBackend, self).__init__(basis)
self.creg = None
self.cval = None
if basis:
@ -72,8 +70,8 @@ class CircuitBackend(UnrollerBackend):
sz = size of the register
"""
assert size >= 0, "invalid qreg size"
q = QuantumRegister(name, size)
self.circuit.add(q)
q_register = QuantumRegister(name, size)
self.circuit.add(q_register)
def new_creg(self, name, size):
"""Create a new classical register.
@ -82,8 +80,8 @@ class CircuitBackend(UnrollerBackend):
sz = size of the register
"""
assert size >= 0, "invalid creg size"
c = ClassicalRegister(name, size)
self.circuit.add(c)
c_register = ClassicalRegister(name, size)
self.circuit.add(c_register)
def define_gate(self, name, gatedata):
"""Define a new quantum gate.
@ -246,11 +244,9 @@ class CircuitBackend(UnrollerBackend):
"ry": [(1, 1), lambda x: self.circuit.ry(x[0][0], x[1][0])],
"rz": [(1, 1), lambda x: self.circuit.rz(x[0][0], x[1][0])],
"s": [(0, 1), lambda x: self.circuit.s(x[1][0])],
"sdg": [(0, 1), lambda x: self.circuit.s(x[1][0]).inverse()
],
"sdg": [(0, 1), lambda x: self.circuit.s(x[1][0]).inverse()],
"t": [(0, 1), lambda x: self.circuit.t(x[1][0]).inverse()],
"tdg": [(0, 1), lambda x: self.circuit.t(x[1][0]).inverse()
],
"tdg": [(0, 1), lambda x: self.circuit.t(x[1][0]).inverse()],
"u1": [(1, 1), lambda x: self.circuit.u1(x[0][0], x[1][0])],
"u2": [(2, 1), lambda x: self.circuit.u2(x[0][0], x[0][1],
x[1][0])],
@ -258,17 +254,16 @@ class CircuitBackend(UnrollerBackend):
x[0][2], x[1][0])],
"x": [(0, 1), lambda x: self.circuit.x(x[1][0])],
"y": [(0, 1), lambda x: self.circuit.y(x[1][0])],
"z": [(0, 1), lambda x: self.circuit.z(x[1][0])],
}
"z": [(0, 1), lambda x: self.circuit.z(x[1][0])]}
if name not in lut:
raise BackendError("gate %s not in standard extensions" %
name)
name)
gate_data = lut[name]
if gate_data[0] != (len(args), len(qubits)):
raise BackendError("gate %s signature (%d, %d) is " %
(name, len(args), len(qubits)) +
"incompatible with the standard " +
"extensions")
(name, len(args), len(qubits)) +
"incompatible with the standard " +
"extensions")
this_gate = gate_data[1]([list(map(lambda x:
x.sym(nested_scope), args)),
list(map(self._map_qubit, qubits))])

View File

@ -31,6 +31,7 @@ class DAGBackend(UnrollerBackend):
basis is a list of operation name strings.
"""
super(DAGBackend, self).__init__(basis)
self.prec = 15
self.creg = None
self.cval = None
@ -135,9 +136,9 @@ class DAGBackend(UnrollerBackend):
"""
if self.listen:
names = []
for x in qubitlists:
for j in range(len(x)):
names.append(x[j])
for qubit in qubitlists:
for j, _ in enumerate(qubit):
names.append(qubit[j])
if "barrier" not in self.basis:
self.basis.append("barrier")
self.circuit.add_basis_element("barrier", -1)

View File

@ -44,7 +44,6 @@ The input is a AST and a basis set and returns a json memory object::
]
}
"""
import json
from qiskit.unroll import BackendError
from qiskit.unroll import UnrollerBackend
@ -58,6 +57,7 @@ class JsonBackend(UnrollerBackend):
basis is a list of operation name strings.
The default basis is ["U", "CX"].
"""
super(JsonBackend, self).__init__(basis)
self.circuit = {}
self.circuit['operations'] = []
self.circuit['header'] = {}
@ -193,7 +193,7 @@ class JsonBackend(UnrollerBackend):
})
self._add_condition()
def measure(self, qubit, cbit):
def measure(self, qubit, bit):
"""Measurement operation.
qubit is (regname, idx) tuple for the input qubit.
@ -202,7 +202,7 @@ class JsonBackend(UnrollerBackend):
if "measure" not in self.basis:
self.basis.append("measure")
qubit_indices = [self._qubit_order_internal.get(qubit)]
clbit_indices = [self._cbit_order_internal.get(cbit)]
clbit_indices = [self._cbit_order_internal.get(bit)]
self.circuit['operations'].append({
'name': 'measure',
'qubits': qubit_indices,
@ -310,5 +310,5 @@ class JsonBackend(UnrollerBackend):
def _is_circuit_valid(self):
"""Checks whether the circuit object is a valid one or not."""
return len(self.circuit['header']) > 0 \
and len(self.circuit['operations']) > 0
return (len(self.circuit['header']) > 0 and
len(self.circuit['operations']) > 0)

View File

@ -33,6 +33,7 @@ class PrinterBackend(UnrollerBackend):
basis is a list of operation name strings.
"""
super(PrinterBackend, self).__init__(basis)
self.prec = 15
self.creg = None
self.cval = None
@ -235,7 +236,7 @@ class PrinterBackend(UnrollerBackend):
if self.creg is not None:
print("if(%s==%d) " % (self.creg, self.cval), end="")
print(name, end="")
if len(args) > 0:
if args:
print("(%s)" % ",".join(map(lambda x:
str(x.sym(nested_scope)),
args)), end="")

View File

@ -56,12 +56,13 @@ class Unroller(object):
Return a list of tuples (name,index).
"""
# pylint: disable=inconsistent-return-statements
if node.type == "indexed_id":
# An indexed bit or qubit
return [(node.name, node.index)]
elif node.type == "id":
# A qubit or qreg or creg
if len(self.bit_stack[-1]) == 0:
if not self.bit_stack[-1]:
# Global scope
if node.name in self.qregs:
return [(node.name, j)
@ -69,18 +70,17 @@ class Unroller(object):
elif node.name in self.cregs:
return [(node.name, j)
for j in range(self.cregs[node.name])]
else:
raise UnrollerError("expected qreg or creg name:",
"line=%s" % node.line,
"file=%s" % node.file)
raise UnrollerError("expected qreg or creg name:",
"line=%s" % node.line,
"file=%s" % node.file)
else:
# local scope
if node.name in self.bit_stack[-1]:
return [self.bit_stack[-1][node.name]]
else:
raise UnrollerError("excepted local bit name:",
"line=%s" % node.line,
"file=%s" % node.file)
raise UnrollerError("excepted local bit name:",
"line=%s" % node.line,
"file=%s" % node.file)
return None
def _process_custom_unitary(self, node):
"""Process a custom unitary node."""
@ -101,8 +101,8 @@ class Unroller(object):
self.arg_stack.append({gargs[j]: args[j]
for j in range(len(gargs))})
# Only index into register arguments.
element = list(map(lambda x: idx * x,
[len(bits[j]) > 1 for j in range(len(bits))]))
element = [idx*x for x in
[len(bits[j]) > 1 for j in range(len(bits))]]
self.bit_stack.append({gbits[j]: bits[j][element[j]]
for j in range(len(gbits))})
self.backend.start_gate(name,
@ -119,7 +119,7 @@ class Unroller(object):
self.bit_stack.pop()
else:
raise UnrollerError("internal error undefined gate:",
"line=%s" % node.line, "file=%s" % node.file)
"line=%s" % node.line, "file=%s" % node.file)
def _process_gate(self, node, opaque=False):
"""Process a gate node.
@ -127,20 +127,20 @@ class Unroller(object):
If opaque is True, process the node as an opaque gate node.
"""
self.gates[node.name] = {}
de = self.gates[node.name]
de["opaque"] = opaque
de["n_args"] = node.n_args()
de["n_bits"] = node.n_bits()
de_gate = self.gates[node.name]
de_gate["opaque"] = opaque
de_gate["n_args"] = node.n_args()
de_gate["n_bits"] = node.n_bits()
if node.n_args() > 0:
de["args"] = [element.name for element in node.arguments.children]
de_gate["args"] = [element.name for element in node.arguments.children]
else:
de["args"] = []
de["bits"] = [c.name for c in node.bitlist.children]
de_gate["args"] = []
de_gate["bits"] = [c.name for c in node.bitlist.children]
if opaque:
de["body"] = None
de_gate["body"] = None
else:
de["body"] = node.body
self.backend.define_gate(node.name, copy.deepcopy(de))
de_gate["body"] = node.body
self.backend.define_gate(node.name, copy.deepcopy(de_gate))
def _process_cnot(self, node):
"""Process a CNOT gate node."""
@ -148,7 +148,7 @@ class Unroller(object):
id1 = self._process_bit_id(node.children[1])
if not(len(id0) == len(id1) or len(id0) == 1 or len(id1) == 1):
raise UnrollerError("internal error: qreg size mismatch",
"line=%s" % node.line, "file=%s" % node.file)
"line=%s" % node.line, "file=%s" % node.file)
maxidx = max([len(id0), len(id1)])
for idx in range(maxidx):
if len(id0) > 1 and len(id1) > 1:
@ -164,7 +164,7 @@ class Unroller(object):
id1 = self._process_bit_id(node.children[1])
if len(id0) != len(id1):
raise UnrollerError("internal error: reg size mismatch",
"line=%s" % node.line, "file=%s" % node.file)
"line=%s" % node.line, "file=%s" % node.file)
for idx, idy in zip(id0, id1):
self.backend.measure(idx, idy)
@ -252,8 +252,8 @@ class Unroller(object):
elif node.type == "reset":
id0 = self._process_bit_id(node.children[0])
for idx in range(len(id0)):
self.backend.reset(id0[idx])
for i, _ in enumerate(id0):
self.backend.reset(id0[i])
elif node.type == "if":
self._process_if(node)
@ -266,8 +266,9 @@ class Unroller(object):
else:
raise UnrollerError("internal error: undefined node type",
node.type, "line=%s" % node.line,
"file=%s" % node.file)
node.type, "line=%s" % node.line,
"file=%s" % node.file)
return None
def set_backend(self, backend):
"""Set the backend object."""

View File

@ -35,7 +35,6 @@ class UnrollerBackend(object):
"""
if basis:
basis = []
raise BackendError("Backend __init__ unimplemented")
def set_basis(self, basis):
"""Declare the set of user-defined gates to emit.
@ -83,6 +82,7 @@ class UnrollerBackend(object):
nested_scope is a list of dictionaries mapping expression variables
to Node expression objects in order of increasing nesting depth.
"""
# pylint: disable=invalid-name
raise BackendError("Backend u unimplemented")
def cx(self, qubit0, qubit1):
@ -91,6 +91,7 @@ class UnrollerBackend(object):
qubit0 is (regname,idx) tuple for the control qubit.
qubit1 is (regname,idx) tuple for the target qubit.
"""
# pylint: disable=invalid-name
raise BackendError("Backend cx unimplemented")
def measure(self, qubit, bit):

View File

@ -27,6 +27,7 @@ class UnrollerError(QISKitError):
def __init__(self, *message):
"""Set the error message."""
super(UnrollerError, self).__init__(*message)
self.message = ' '.join(message)
def __str__(self):

View File

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# 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
#
# http://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.
# =============================================================================

View File

@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# =============================================================================
"""QISKit unit tests."""
import os

View File

@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# =============================================================================
"""Generate random circuits."""
import random
@ -35,29 +36,30 @@ def choices(population, weights=None, k=1):
return numpy.random.choice(population, size=k, p=weights)
class RandomCircuitGenerator():
class RandomCircuitGenerator(object):
"""
Generate random size circuits for profiling.
"""
def __init__(self, seed=None,
maxQubits=5, minQubits=1,
maxDepth=100, minDepth=1):
max_qubits=5, min_qubits=1,
max_depth=100, min_depth=1):
"""
Args:
seed (int): Random number seed. If none, don't seed the generator.
minDepth int): Minimum number of operations in circuit.
maxDepth (int): Maximum number of operations in a circuit.
minQubits (int): Minimum number of operations in a cirucit.
maxQubits (int): Maximum number of qubits in a circuit.
max_qubits (int): Maximum number of qubits in a circuit.
min_qubits (int): Minimum number of operations in a cirucit.
max_depth (int): Maximum number of operations in a circuit.
min_depth (int): Minimum number of operations in circuit.
"""
self.maxDepth = maxDepth
self.maxQubits = maxQubits
self.minDepth = minDepth
self.minQubits = minQubits
self.max_depth = max_depth
self.max_qubits = max_qubits
self.min_depth = min_depth
self.min_qubits = min_qubits
self.circuit_list = []
self.nQubit_list = []
self.n_qubit_list = []
self.depth_list = []
self.basis_gates = None
self.circuit_name_list = []
if seed is not None:
random.seed(a=seed)
# specify number of parameters and args for each op
@ -65,7 +67,7 @@ class RandomCircuitGenerator():
# maybe we can guess this. "nregs" are the number of qubits the
# operation uses. If nregs=0 then it means either 1 qubit or
# 1 register. "nparams" are the number of parameters the operation takes.
self.opSignature = {
self.op_signature = {
'barrier': {'nregs': 0, 'nparams': None},
'ccx': {'nregs': 3, 'nparams': None},
'ch': {'nregs': 2, 'nparams': None},
@ -82,7 +84,7 @@ class RandomCircuitGenerator():
'reset': {'nregs': 1, 'nparams': None},
'rx': {'nregs': 1, 'nparams': 1},
'ry': {'nregs': 1, 'nparams': 1},
'rz': {'nregs': 1, 'nparams': 1},
'rz': {'nregs': 1, 'nparams': 1},
's': {'nregs': 1, 'nparams': None},
't': {'nregs': 1, 'nparams': None},
'u1': {'nregs': 1, 'nparams': 1},
@ -92,7 +94,7 @@ class RandomCircuitGenerator():
'y': {'nregs': 1, 'nparams': None},
'z': {'nregs': 1, 'nparams': None}}
def add_circuits(self, nCircuits, doMeasure=True, basis=None,
def add_circuits(self, n_circuits, do_measure=True, basis=None,
basis_weights=None):
"""Adds circuits to program.
@ -101,19 +103,21 @@ class RandomCircuitGenerator():
[1,nQubits] to end of circuit.
Args:
nCircuits (int): Number of circuits to add.
doMeasure (bool): Whether to add measurements.
basis (list(str) | None): List of op names. If None, basis
n_circuits (int): Number of circuits to add.
do_measure (bool): Whether to add measurements.
basis (list(str) or None): List of op names. If None, basis
is randomly chosen with unique ops in (2,7)
basis_weights (list of float or None): List of weights
basis_weights (list(float) or None): List of weights
corresponding to indices in `basis`.
Raises:
AttributeError: if operation is not recognized.
"""
if basis is None:
basis = list(random.sample(self.opSignature.keys(),
random.randint(2,7)))
basis = list(random.sample(self.op_signature.keys(),
random.randint(2, 7)))
basis_weights = [1./len(basis)] * len(basis)
if basis_weights is not None:
assert(len(basis) == len(basis_weights))
assert len(basis) == len(basis_weights)
uop_basis = basis[:]
if basis_weights:
uop_basis_weights = basis_weights[:]
@ -133,106 +137,106 @@ class RandomCircuitGenerator():
del uop_basis_weights[ind]
# self.basis_gates = uop_basis
self.basis_gates = basis
self.circuitNameList = []
self.circuit_name_list = []
# TODO: replace choices with random.choices() when python 3.6 is
# required.
self.nQubit_list = choices(
range(self.minQubits, self.maxQubits+1), k=nCircuits)
self.n_qubit_list = choices(
range(self.min_qubits, self.max_qubits + 1), k=n_circuits)
self.depth_list = choices(
range(self.minDepth, self.maxDepth+1), k=nCircuits)
for iCircuit in range(nCircuits):
nQubits = self.nQubit_list[iCircuit]
if self.min_regs_exceeds_nqubits(uop_basis, nQubits):
range(self.min_depth, self.max_depth + 1), k=n_circuits)
for i_circuit in range(n_circuits):
n_qubits = self.n_qubit_list[i_circuit]
if self.min_regs_exceeds_nqubits(uop_basis, n_qubits):
# no gate operation from this circuit can fit in the available
# number of qubits.
continue
depthCnt = self.depth_list[iCircuit]
regpop = numpy.arange(1, nQubits+1)
registerWeights = regpop[::-1].astype(float)
registerWeights /= registerWeights.sum()
maxRegisters = numpy.random.choice(regpop, p=registerWeights)
regWeight = numpy.ones(maxRegisters) / float(maxRegisters)
regSizes = rand_register_sizes(nQubits, regWeight)
nRegisters = len(regSizes)
depth_cnt = self.depth_list[i_circuit]
reg_pop = numpy.arange(1, n_qubits+1)
register_weights = reg_pop[::-1].astype(float)
register_weights /= register_weights.sum()
max_registers = numpy.random.choice(reg_pop, p=register_weights)
reg_weight = numpy.ones(max_registers) / float(max_registers)
reg_sizes = rand_register_sizes(n_qubits, reg_weight)
n_registers = len(reg_sizes)
circuit = QuantumCircuit()
for isize, size in enumerate(regSizes):
cr_name = 'cr' + str(isize)
qr_name = 'qr' + str(isize)
cr = ClassicalRegister(cr_name, size)
qr = QuantumRegister(qr_name, size)
circuit.add(qr, cr)
while depthCnt > 0:
for i_size, size in enumerate(reg_sizes):
cr_name = 'cr' + str(i_size)
qr_name = 'qr' + str(i_size)
creg = ClassicalRegister(cr_name, size)
qreg = QuantumRegister(qr_name, size)
circuit.add(qreg, creg)
while depth_cnt > 0:
# TODO: replace choices with random.choices() when python 3.6
# is required.
opName = choices(basis, weights=basis_weights)[0]
if hasattr(circuit, opName):
op = getattr(circuit, opName)
op_name = choices(basis, weights=basis_weights)[0]
if hasattr(circuit, op_name):
operator = getattr(circuit, op_name)
else:
raise AttributeError('operation \"{0}\"'
' not recognized'.format(opName))
nregs = self.opSignature[opName]['nregs']
nparams = self.opSignature[opName]['nparams']
if nregs == 0: # this is a barrier or measure
nregs = random.randint(1, nQubits)
if nQubits >= nregs:
' not recognized'.format(op_name))
n_regs = self.op_signature[op_name]['nregs']
n_params = self.op_signature[op_name]['nparams']
if n_regs == 0: # this is a barrier or measure
n_regs = random.randint(1, n_qubits)
if n_qubits >= n_regs:
# warning: assumes op function signature specifies
# op parameters before qubits
op_args = []
if nparams:
op_args = [random.random() for p in range(nparams)]
if opName == 'measure':
if n_params:
op_args = [random.random() for _ in range(n_params)]
if op_name == 'measure':
# if measure occurs here, assume it's to do a conditional
# randomly select a register to measure
ireg = random.randint(0, nRegisters-1)
ireg = random.randint(0, n_registers-1)
qr_name = 'qr' + str(ireg)
cr_name = 'cr' + str(ireg)
qreg = circuit.regs[qr_name]
creg = circuit.regs[cr_name]
for qind in range(qreg.size):
op(qreg[qind], creg[qind])
operator(qreg[qind], creg[qind])
ifval = random.randint(0, (1 << qreg.size) - 1)
# TODO: replace choices with random.choices() when
# python 3.6 is required.
uopName = choices(uop_basis, weights=uop_basis_weights)[0]
if hasattr(circuit, uopName):
uop = getattr(circuit, uopName)
uop_name = choices(uop_basis, weights=uop_basis_weights)[0]
if hasattr(circuit, uop_name):
uop = getattr(circuit, uop_name)
else:
raise AttributeError('operation \"{0}\"'
' not recognized'.format(uopName))
unregs = self.opSignature[uopName]['nregs']
unparams = self.opSignature[uopName]['nparams']
if unregs == 0: # this is a barrier or measure
unregs = random.randint(1, nQubits)
' not recognized'.format(uop_name))
unregs = self.op_signature[uop_name]['nregs']
unparams = self.op_signature[uop_name]['nparams']
if unregs == 0: # this is a barrier or measure
unregs = random.randint(1, n_qubits)
if qreg.size >= unregs:
qindList = random.sample(range(qreg.size), unregs)
qind_list = random.sample(range(qreg.size), unregs)
uop_args = []
if unparams:
uop_args = [random.random() for p in range(unparams)]
uop_args.extend([qreg[qind] for qind in qindList])
uop_args = [random.random() for _ in range(unparams)]
uop_args.extend([qreg[qind] for qind in qind_list])
uop(*uop_args).c_if(creg, ifval)
depthCnt -= 1
elif opName == 'barrier':
ireg = random.randint(0, nRegisters-1)
depth_cnt -= 1
elif op_name == 'barrier':
ireg = random.randint(0, n_registers-1)
qr_name = 'qr' + str(ireg)
qreg = circuit.regs[qr_name]
bar_args = [(qreg, mi) for mi in range(qreg.size)]
op(*bar_args)
operator(*bar_args)
else:
# select random register
ireg = random.randint(0, nRegisters-1)
ireg = random.randint(0, n_registers-1)
qr_name = 'qr' + str(ireg)
qreg = circuit.regs[qr_name]
if qreg.size >= nregs:
qindList = random.sample(range(qreg.size), nregs)
op_args.extend([qreg[qind] for qind in qindList])
op(*op_args)
depthCnt -= 1
if qreg.size >= n_regs:
qind_list = random.sample(range(qreg.size), n_regs)
op_args.extend([qreg[qind] for qind in qind_list])
operator(*op_args)
depth_cnt -= 1
else:
break
nmeasure = random.randint(1, nQubits)
mList = random.sample(range(nmeasure), nmeasure)
if doMeasure:
for qind in mList:
nmeasure = random.randint(1, n_qubits)
m_list = random.sample(range(nmeasure), nmeasure)
if do_measure:
for qind in m_list:
rind = 0 # register index
cumtot = 0
while qind >= cumtot + circuit.regs['qr' + str(rind)].size:
@ -244,32 +248,37 @@ class RandomCircuitGenerator():
circuit.measure(qreg[qrind], creg[qrind])
self.circuit_list.append(circuit)
def min_regs_exceeds_nqubits(self, basis, nQubits):
def min_regs_exceeds_nqubits(self, basis, n_qubits):
"""Check whether the minimum number of qubits used by the operations
in basis is between 1 and the number of qubits.
Args:
basis (list): list of basis names
nQubits (int): number of qubits in circuit
n_qubits (int): number of qubits in circuit
Returns:
boolean: result of the check.
"""
return not any((nQubits >= self.opSignature[opName]['nregs'] > 0
return not any((n_qubits >= self.op_signature[opName]['nregs'] > 0
for opName in basis))
def get_circuits(self, format='dag'):
def get_circuits(self, format_='dag'):
"""Get the compiled circuits generated.
Args:
format (str, optional): "qasm" | "qobj" | "QuantumCircuit"
format_ (str, optional): "qasm" | "qobj" | "QuantumCircuit"
Returns:
List of Compiled QuantumCircuit objects.
list: List of Compiled QuantumCircuit objects.
Raises:
NameError: if the output format is not valid.
"""
if format is 'qasm':
if format_ == 'qasm':
qasm_list = []
for circuit in self.circuit_list:
qasm_list.append(circuit.qasm())
return qasm_list
elif format is 'qobj':
elif format_ == 'qobj':
json_list = []
for circuit in self.circuit_list:
node_circuit = qasm.Qasm(data=circuit.qasm()).parse()
@ -278,7 +287,7 @@ class RandomCircuitGenerator():
unroll.JsonBackend(self.basis_gates))
json_list.append(unrolled_circuit.execute())
return json_list
elif format is 'QuantumCircuit':
elif format_ == 'QuantumCircuit':
qc_list = []
for circuit in self.circuit_list:
node_circuit = qasm.Qasm(data=circuit.qasm()).parse()
@ -298,10 +307,10 @@ class RandomCircuitGenerator():
# return qc_list
else:
raise NameError('Unrecognized circuit output format: "{}"'.format(
format))
format_))
def rand_register_sizes(nRegisters, pvals):
"""Return a randomly chosen list of nRegisters summing to nQubits
"""
v = numpy.random.multinomial(nRegisters, pvals)
return v[v.nonzero()]
def rand_register_sizes(n_registers, pvals):
"""Return a randomly chosen list of nRegisters summing to nQubits."""
vector = numpy.random.multinomial(n_registers, pvals)
return vector[vector.nonzero()]

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=missing-docstring
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -23,33 +24,35 @@ import numpy
from qiskit import QuantumProgram
class RandomQasmGenerator():
class RandomQasmGenerator(object):
"""
Generate random size circuits for profiling.
"""
def __init__(self, seed=None,
maxQubits=5, minQubits=1,
maxDepth=100, minDepth=1):
max_qubits=5, min_qubits=1,
max_depth=100, min_depth=1):
"""
Args:
seed: Random number seed. If none, don't seed the generator.
maxDepth: Maximum number of operations in a circuit.
maxQubits: Maximum number of qubits in a circuit.
seed (int): Random number seed. If none, don't seed the generator.
max_qubits (int): Maximum number of qubits in a circuit.
min_qubits (int): Minimum number of qubits in a circuit.
max_depth (int): Maximum number of operations in a circuit.
min_depth (int): Minimum number of operations in a circuit.
"""
self.maxDepth = maxDepth
self.maxQubits = maxQubits
self.minDepth = minDepth
self.minQubits = minQubits
self.qp = QuantumProgram()
self.qr = self.qp.create_quantum_register('qr', maxQubits)
self.cr = self.qp.create_classical_register('cr', maxQubits)
self.circuitNameList = []
self.nQubitList = []
self.depthList = []
self.max_depth = max_depth
self.max_qubits = max_qubits
self.min_depth = min_depth
self.min_qubits = min_qubits
self.qprogram = QuantumProgram()
self.qreg = self.qprogram.create_quantum_register('qr', max_qubits)
self.creg = self.qprogram.create_classical_register('cr', max_qubits)
self.circuit_name_list = []
self.n_qubit_list = []
self.depth_list = []
if seed is not None:
random.seed(a=seed)
def add_circuits(self, nCircuits, doMeasure=True):
def add_circuits(self, n_circuits, do_measure=True):
"""Adds circuits to program.
Generates a circuit with a random number of operations equally weighted
@ -57,43 +60,44 @@ class RandomQasmGenerator():
[1,nQubits] to end of circuit.
Args:
nCircuits (int): Number of circuits to add.
doMeasure (boolean): whether to add measurements
n_circuits (int): Number of circuits to add.
do_measure (boolean): whether to add measurements
"""
self.circuitNameList = []
self.nQubitList = numpy.random.choice(
range(self.minQubits, self.maxQubits+1), size=nCircuits)
self.depthList = numpy.random.choice(
range(self.minDepth, self.maxDepth+1), size=nCircuits)
for i in range(nCircuits):
circuitName = ''.join(numpy.random.choice(
self.circuit_name_list = []
self.n_qubit_list = numpy.random.choice(
range(self.min_qubits, self.max_qubits + 1), size=n_circuits)
self.depth_list = numpy.random.choice(
range(self.min_depth, self.max_depth + 1), size=n_circuits)
for i in range(n_circuits):
circuit_name = ''.join(numpy.random.choice(
list(string.ascii_letters + string.digits), size=10))
self.circuitNameList.append(circuitName)
nQubits = self.nQubitList[i]
depth = self.depthList[i]
circuit = self.qp.create_circuit(circuitName, [self.qr], [self.cr])
for j in range(depth):
if nQubits == 1:
opInd = 0
self.circuit_name_list.append(circuit_name)
n_qubits = self.n_qubit_list[i]
depth = self.depth_list[i]
circuit = self.qprogram.create_circuit(circuit_name,
[self.qreg], [self.creg])
for _ in range(depth):
if n_qubits == 1:
op_ind = 0
else:
opInd = random.randint(0, 1)
if opInd == 0: # U3
qind = random.randint(0, nQubits-1)
op_ind = random.randint(0, 1)
if op_ind == 0: # U3
qind = random.randint(0, n_qubits-1)
circuit.u3(random.random(), random.random(), random.random(),
self.qr[qind])
elif opInd == 1: # CX
source, target = random.sample(range(nQubits), 2)
circuit.cx(self.qr[source], self.qr[target])
nmeasure = random.randint(1, nQubits)
for j in range(nmeasure):
qind = random.randint(0, nQubits-1)
if doMeasure:
self.qreg[qind])
elif op_ind == 1: # CX
source, target = random.sample(range(n_qubits), 2)
circuit.cx(self.qreg[source], self.qreg[target])
n_measure = random.randint(1, n_qubits)
for _ in range(n_measure):
qind = random.randint(0, n_qubits-1)
if do_measure:
# doing this if here keeps the RNG from depending on
# whether measurements are done.
circuit.measure(self.qr[qind], self.cr[qind])
circuit.measure(self.qreg[qind], self.creg[qind])
def get_circuit_names(self):
return self.circuitNameList
return self.circuit_name_list
def getProgram(self):
return self.qp
def get_program(self):
return self.qprogram

View File

@ -75,5 +75,7 @@ class QiskitTestCase(unittest.TestCase):
Args:
filename (string): filename or relative path to the resource.
path (Path): path used as relative to the filename.
Returns:
str: the absolute path to the resource.
"""
return os.path.normpath(os.path.join(path.value, filename))

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name,missing-docstring
# pylint: disable=invalid-name,missing-docstring,no-member
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
@ -20,12 +20,10 @@ import os
from unittest import skipIf
from unittest.mock import patch
from qiskit import QuantumProgram, QISKitError
from IBMQuantumExperience.IBMQuantumExperience import _Request
from qiskit import QuantumProgram, QISKitError
from .common import QiskitTestCase
# We need the environment variable for Travis.
HAS_GROUP_VARS = False
try:
@ -123,7 +121,6 @@ class TestApiHub(QiskitTestCase):
['qc'], backend=self.backend, shots=1, max_credits=3)
self.assertIn('Backend ibmqx4 not found!', str(context.exception))
@skipIf(not HAS_GROUP_VARS, 'QE group variables not present')
def test_execute_api_modified_parameters(self):
"""Test calling the API with modified hub parameters."""

View File

@ -19,14 +19,13 @@
import unittest
from scipy import linalg as la
import numpy as np
from scipy import linalg as la
from qiskit.tools.apps.optimization import (Energy_Estimate, make_Hamiltonian,
Hamiltonian_from_file,
trial_circuit_ry)
from qiskit.tools.qi.pauli import Pauli
from .common import QiskitTestCase
@ -61,6 +60,7 @@ class TestQuantumOptimization(QiskitTestCase):
class TestHamiltonian(QiskitTestCase):
def test_hamiltonian(self):
# pylint: disable=unexpected-keyword-arg
# printing an example from a H2 file
hfile = self._get_resource_path("H2Equilibrium.txt")
hamiltonian = make_Hamiltonian(Hamiltonian_from_file(hfile))

View File

@ -1,5 +1,21 @@
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name,missing-docstring
# Copyright 2017 IBM RESEARCH. All Rights Reserved.
#
# 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
#
# http://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 unittest
from qiskit import QISKitError
@ -9,12 +25,12 @@ from qiskit.backends import (BaseBackend,
register_backend)
from qiskit.backends._backendutils import (_REGISTERED_BACKENDS,
discover_local_backends)
from .common import QiskitTestCase
class TestBaseBackend(QiskitTestCase):
def setUp(self):
# pylint: disable=redefined-outer-name,unused-variable
QiskitTestCase.setUp(self)
# Manually clear and populate the list of registered backends, as it is
@ -50,6 +66,7 @@ class TestBaseBackend(QiskitTestCase):
self.assertEqual(initial_backends_len, len(_REGISTERED_BACKENDS))
def test_fail_incomplete_implementation(self):
# pylint: disable=abstract-method,super-init-not-called,abstract-class-instantiated
class SubclassTest(BaseBackend):
def __init__(self, qobj):
pass
@ -67,21 +84,20 @@ class TestBaseBackend(QiskitTestCase):
def test_local_backends(self):
available_backends = local_backends()
self.log.info('The discovered local devices are: {}'.format(
available_backends))
self.log.info('The discovered local devices are: %s', available_backends)
# Some local backends should always be present.
self.assertIn('local_qasm_simulator', available_backends)
self.assertIn('local_unitary_simulator', available_backends)
def test_remote_backends(self):
self.log.info('The discovered remote devices are: {}'.format(
remote_backends()))
self.log.info('The discovered remote devices are: %s', remote_backends())
# Dummy backend classes for testing registration.
class NoConfigurationBackend(BaseBackend):
def __init__(self, configuration=None):
# pylint: disable=super-init-not-called
pass
def run(self, q_job):
@ -94,8 +110,9 @@ class NoConfigurationBackend(BaseBackend):
class ValidBackend(NoConfigurationBackend):
def __init__(self, configuration=None):
if configuration == None:
self._configuration = {'name':'valid_backend'}
# pylint: disable=super-init-not-called
if not configuration:
self._configuration = {'name': 'valid_backend'}
else:
self._configuration = configuration
@ -106,6 +123,7 @@ class ValidBackend(NoConfigurationBackend):
class UninstantiableBackend(ValidBackend):
def __init__(self):
# pylint: disable=super-init-not-called
raise Exception

Some files were not shown because too many files have changed in this diff Show More