From b36fa56ccdcc9b494d6d9eed9d9a99d557031fa9 Mon Sep 17 00:00:00 2001 From: Christopher Wood Date: Mon, 21 May 2018 10:52:28 -0400 Subject: [PATCH 01/22] Fix state_tomography.py to use local_statevector_simulator (#481) --- test/performance/state_tomography.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/performance/state_tomography.py b/test/performance/state_tomography.py index a866de397943..750ebf5dfefc 100644 --- a/test/performance/state_tomography.py +++ b/test/performance/state_tomography.py @@ -98,7 +98,7 @@ def state_tomography(state, n_qubits, shots): # Prepared target state and assess quality qp = target_prep(qp, state, target) - prep_result = qp.execute(['prep'], backend=backend, shots=1) + prep_result = qp.execute(['prep'], backend='local_statevector_simulator') prep_state = prep_result.get_data('prep')['statevector'] F_prep = state_fidelity(prep_state, target) print('Prepared state fidelity =', F_prep) From ea5e45b7449d3afb149c51f9c4b5f7fd539e2977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20M=2E=20Rodr=C3=ADguez?= Date: Mon, 21 May 2018 18:45:02 +0200 Subject: [PATCH 02/22] Fix potentially block local job test (#489) Make the `TestLocalJob:test_run_async()` wait for the jobs to be completed, marking it as a slow_test as a result, as otherwise it might have affect subsequent tests due to filling up the executor queue with the jobs running in the background even after the test was finished. --- test/python/test_localjob.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/test/python/test_localjob.py b/test/python/test_localjob.py index 88a6a59376f5..bccec6cf55fc 100644 --- a/test/python/test_localjob.py +++ b/test/python/test_localjob.py @@ -30,7 +30,7 @@ from qiskit import (ClassicalRegister, QuantumCircuit, QuantumRegister, QuantumJob) from qiskit.backends.local import LocalProvider, LocalJob -from .common import requires_qe_access, QiskitTestCase +from .common import requires_qe_access, QiskitTestCase, slow_test class TestLocalJob(QiskitTestCase): @@ -53,6 +53,14 @@ def setUpClass(cls, QE_TOKEN, QE_URL, hub=None, group=None, project=None): cls._qc = qc cls._provider = LocalProvider(QE_TOKEN, QE_URL, hub, group, project) + def setUp(self): + # Store the original executor, for restoring later. + self._original_executor = LocalJob._executor + + def tearDown(self): + # Restore the original executor. + LocalJob._executor = self._original_executor + def test_run(self): backend = self._provider.get_backend('local_qasm_simulator_py') qobj = qiskit._compiler.compile(self._qc, backend) @@ -69,6 +77,7 @@ def test_run(self): self.log.info('chi2_contingency: %s', str(contingency)) self.assertGreater(contingency[1], 0.01) + @slow_test def test_run_async(self): if sys.platform == 'darwin': LocalJob._executor = futures.ThreadPoolExecutor(max_workers=2) @@ -111,6 +120,15 @@ def test_run_async(self): '{0} s'.format(timeout)) time.sleep(1) + # Wait for all the jobs to finish. + # TODO: this causes the test to wait until the 15 qubit jobs are + # finished, which might take long (hence the @slow_test). Waiting for + # the result is needed as otherwise the jobs would still be running + # once the test is completed, causing failures in subsequent tests as + # the executor's queue might be overloaded. + + _ = [job.result() for job in job_array] + def test_cancel(self): """Test the cancelation of jobs. @@ -161,6 +179,9 @@ def test_cancel(self): '{0} s'.format(timeout)) time.sleep(1) + # Wait for all the jobs to finish. + _ = [job.result() for job in job_array if not job.cancelled] + def test_done(self): backend = self._provider.get_backend('local_qasm_simulator_py') qobj = qiskit._compiler.compile(self._qc, backend) From f7995fffe9087fa1f1afa98b4a93f84166f33b27 Mon Sep 17 00:00:00 2001 From: ewinston Date: Mon, 21 May 2018 12:45:28 -0400 Subject: [PATCH 03/22] job cancellation improvements for hubs (#486) * job cancellation improvements for hubs * remove unused global --- qiskit/backends/ibmq/ibmqjob.py | 5 ++-- test/python/test_ibmqjob.py | 44 +++++++++++++++++++++++++++------ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/qiskit/backends/ibmq/ibmqjob.py b/qiskit/backends/ibmq/ibmqjob.py index 031a265994d6..e0f81bdb523e 100644 --- a/qiskit/backends/ibmq/ibmqjob.py +++ b/qiskit/backends/ibmq/ibmqjob.py @@ -81,7 +81,6 @@ def result(self, timeout=None, wait=5): def cancel(self): """Attempt to cancel job. Currently this is only possible on commercial systems. - Returns: bool: True if job can be cancelled, else False. @@ -131,7 +130,7 @@ def status(self): stats['queue_position'] = job_result['infoQueue']['position'] elif job_result['status'] == 'COMPLETED': self._status = JobStatus.DONE - elif self.cancelled: + elif job_result['status'] == 'CANCELLED': self._status = JobStatus.CANCELLED elif self.exception: self._status = JobStatus.ERROR @@ -207,7 +206,7 @@ def exception(self): def _is_commercial(self): config = self._api.config # this check may give false positives so should probably be improved - return config['hub'] and config['group'] and config['project'] + return config.get('hub') and config.get('group') and config.get('project') @property def job_id(self): diff --git a/test/python/test_ibmqjob.py b/test/python/test_ibmqjob.py index 25a6ec68daf1..75a52ce0cbd1 100644 --- a/test/python/test_ibmqjob.py +++ b/test/python/test_ibmqjob.py @@ -27,7 +27,8 @@ from qiskit import (ClassicalRegister, QuantumCircuit, QuantumRegister, QuantumJob) import qiskit._compiler -from qiskit.backends.ibmq import IBMQProvider, IBMQJob +from qiskit.backends.ibmq import IBMQProvider +from qiskit.backends.ibmq.ibmqjob import IBMQJob, IBMQJobError from qiskit.backends.basejob import JobStatus from .common import requires_qe_access, QiskitTestCase, slow_test @@ -59,6 +60,7 @@ def setUpClass(cls, QE_TOKEN, QE_URL, hub=None, group=None, project=None): qc.measure(qr, cr) cls._qc = qc cls._provider = IBMQProvider(QE_TOKEN, QE_URL, hub, group, project) + cls._using_hub = bool(hub and group and project) def test_run_simulator(self): backend = self._provider.get_backend('ibmq_qasm_simulator') @@ -202,14 +204,42 @@ def test_run_async_device(self): job_ids = [job.job_id for job in job_array] self.assertEqual(sorted(job_ids), sorted(list(set(job_ids)))) - @unittest.skip('cancel is not currently possible on IBM Q') def test_cancel(self): - backend = self._provider.get_backend('ibmqx4') - qobj = qiskit._compiler.compile(self._qc, backend) + if not self._using_hub: + self.skipTest('job cancellation currently only available on hubs') + backends = self._provider.available_backends({'simulator': False}) + self.log.info('devices: %s', [b.name for b in backends]) + backend = backends[0] + self.log.info('using backend: %s', backend.name) + num_qubits = 5 + qr = QuantumRegister(num_qubits, 'qr') + cr = ClassicalRegister(num_qubits, 'cr') + qc = QuantumCircuit(qr, cr) + for i in range(num_qubits-1): + qc.cx(qr[i], qr[i+1]) + qc.measure(qr, cr) + qobj = qiskit._compiler.compile(qc, backend) quantum_job = QuantumJob(qobj, backend, preformatted=True) - job = backend.run(quantum_job) - job.cancel() - self.assertTrue(job.cancelled) + num_jobs = 3 + job_array = [backend.run(quantum_job) for _ in range(num_jobs)] + success = False + self.log.info('jobs submitted: %s', num_jobs) + while any([job.status['status'] == JobStatus.INITIALIZING for job in job_array]): + self.log.info('jobs initializing') + time.sleep(1) + for job in job_array: + job.cancel() + while not success: + job_status = [job.status for job in job_array] + for status in job_status: + self.log.info(status) + if any([status['status'] == JobStatus.CANCELLED for status in job_status]): + success = True + if all([status['status'] == JobStatus.DONE for status in job_status]): + raise IBMQJobError('all jobs completed before any could be cancelled') + self.log.info('-' * 20) + time.sleep(2) + self.assertTrue(success) def test_job_id(self): backend = self._provider.get_backend('ibmq_qasm_simulator') From f8e9280a5f1ee413a8e3b9258e7509b080667d86 Mon Sep 17 00:00:00 2001 From: "Diego M. Rodriguez" Date: Tue, 22 May 2018 10:57:23 +0200 Subject: [PATCH 04/22] Revise appveyor test verbosity --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index a43b47a79ca0..ea47a6b98090 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -42,7 +42,7 @@ install: # Use py.test for output of xunit test results. test_script: - - py.test -v --junit-xml=test_results.xml + - py.test -v --tb=short --junit-xml=test_results.xml # Upload the test results to appveyor so they are shown on the "Tests" tab. on_finish: From ee59a8f682484bf53b791b0b04f29e21ee21b6df Mon Sep 17 00:00:00 2001 From: Paul Nation Date: Tue, 22 May 2018 12:46:00 -0400 Subject: [PATCH 05/22] Fix compiler seed hardcoded to 13 (#482) * Fix compiler seed hardcoded. * Allow seed to be set --- qiskit/_compiler.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qiskit/_compiler.py b/qiskit/_compiler.py index f6d87efc604b..7bcafa6c87f6 100644 --- a/qiskit/_compiler.py +++ b/qiskit/_compiler.py @@ -169,7 +169,7 @@ def compile(circuits, backend, def compile_circuit(quantum_circuit, basis_gates='u1,u2,u3,cx,id', coupling_map=None, - initial_layout=None, get_layout=False, format='dag'): + initial_layout=None, get_layout=False, format='dag', seed=None): """Compile the circuit. This builds the internal "to execute" list which is list of quantum @@ -204,6 +204,7 @@ def compile_circuit(quantum_circuit, basis_gates='u1,u2,u3,cx,id', coupling_map= get_layout (bool): flag for returning the layout. format (str): The target format of the compilation: {'dag', 'json', 'qasm'} + seed (int): random seed for simulators Returns: object: If get_layout == False, the compiled circuit in the specified @@ -227,7 +228,7 @@ def compile_circuit(quantum_circuit, basis_gates='u1,u2,u3,cx,id', coupling_map= coupling = Coupling(coupling_list2dict(coupling_map)) logger.info("initial layout: %s", initial_layout) compiled_dag_circuit, final_layout = swap_mapper( - compiled_dag_circuit, coupling, initial_layout, trials=20, seed=13) + compiled_dag_circuit, coupling, initial_layout, trials=20, seed=seed) logger.info("final layout: %s", final_layout) # Expand swaps dag_unroller = DagUnroller(compiled_dag_circuit, DAGBackend(basis)) From ae99d5982c85975f0a9adb8baf9830ee32239db8 Mon Sep 17 00:00:00 2001 From: Paul Nation Date: Wed, 23 May 2018 04:26:19 -0400 Subject: [PATCH 06/22] Fix mapping error for multiple qregs raised in #492 (#494) * Fix mapping error for multipl qreg. * better unittest --- qiskit/_compiler.py | 10 +++++----- test/python/test_compiler.py | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/qiskit/_compiler.py b/qiskit/_compiler.py index 7bcafa6c87f6..4bb0448a19f0 100644 --- a/qiskit/_compiler.py +++ b/qiskit/_compiler.py @@ -135,13 +135,13 @@ def compile(circuits, backend, # Pick good initial layout if None is given and not simulator if initial_layout is None and not backend.configuration['simulator']: best_sub = best_subset(backend, num_qubits) - qreg_list = [] + initial_layout = {} + map_iter = 0 for key, value in circuit.get_qregs().items(): - qreg_list += [key]*len(value) + for i in range(value.size): + initial_layout[(key, i)] = ('q', best_sub[map_iter]) + map_iter += 1 - initial_layout = {(rr, kk): ('q', best_sub[kk]) - for rr in qreg_list - for kk in range(len(qreg_list))} dag_circuit, final_layout = compile_circuit( circuit, basis_gates=basis_gates, diff --git a/test/python/test_compiler.py b/test/python/test_compiler.py index 34d4403497a9..a7797371b3ae 100644 --- a/test/python/test_compiler.py +++ b/test/python/test_compiler.py @@ -346,6 +346,29 @@ def test_mapping_correction(self, QE_TOKEN, QE_URL, hub=None, group=None, projec qobj = None self.assertIsInstance(qobj, dict) + @requires_qe_access + def test_mapping_multi_qreg(self, QE_TOKEN, QE_URL, hub=None, group=None, project=None): + """Test mapping works for multiple qregs. + """ + provider = IBMQProvider(QE_TOKEN, QE_URL, hub, group, project) + backend = provider.get_backend('ibmqx5') + + q = qiskit.QuantumRegister(3, name='qr') + q2 = qiskit.QuantumRegister(1, name='qr2') + q3 = qiskit.QuantumRegister(4, name='qr3') + c = qiskit.ClassicalRegister(3, name='cr') + qc = qiskit.QuantumCircuit(q, q2, q3, c) + qc.h(q[0]) + qc.cx(q[0], q2[0]) + qc.cx(q[1], q3[2]) + qc.measure(q, c) + + try: + qobj = qiskit._compiler.compile(qc, backend) + except QISKitError: + qobj = None + self.assertIsInstance(qobj, dict) + if __name__ == '__main__': unittest.main(verbosity=2) From 156672ce1e32647db3c36451a9883c0479857fd8 Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Wed, 23 May 2018 14:04:07 +0100 Subject: [PATCH 07/22] fix link to .github/CONTRIBUTING.rst (#495) --- CONTRIBUTORS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 7867fb2923c9..efe05315f00c 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -25,5 +25,5 @@ involved in the project: * Erick Winston * Chris Wood -If you [contribute to the project](CONTRIBUTING.rst), you are welcome to include +If you [contribute to the project](.github/CONTRIBUTING.rst), you are welcome to include your name in this list. From 2e7187b1b68f0aca063c0d991f8d5b25302244d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abd=C3=B3n=20Rodr=C3=ADguez=20Davila?= Date: Wed, 23 May 2018 15:37:04 +0200 Subject: [PATCH 08/22] Move code of conduct inside .github folder (#496) --- CODE_OF_CONDUCT.md => .github/CODE_OF_CONDUCT.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename CODE_OF_CONDUCT.md => .github/CODE_OF_CONDUCT.md (100%) diff --git a/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md similarity index 100% rename from CODE_OF_CONDUCT.md rename to .github/CODE_OF_CONDUCT.md From ec6f9daf174bbd6bd00de6d1d9e12cba1581c018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abd=C3=B3n=20Rodr=C3=ADguez=20Davila?= Date: Wed, 23 May 2018 16:50:54 +0200 Subject: [PATCH 09/22] [skip ci] Move dev cycle to contributing (#497) --- .github/CONTRIBUTING.rst | 112 ++++++++++++++++++++++++++++++++------- DEVELOPMENT_CYCLE.md | 47 ---------------- 2 files changed, 94 insertions(+), 65 deletions(-) delete mode 100644 DEVELOPMENT_CYCLE.md diff --git a/.github/CONTRIBUTING.rst b/.github/CONTRIBUTING.rst index 09eed6c5ee64..fc4c9530ef3e 100644 --- a/.github/CONTRIBUTING.rst +++ b/.github/CONTRIBUTING.rst @@ -204,30 +204,29 @@ All platforms: .. code:: sh - $> cd out - out$> make lint - out$> make style + $> cd out + out$> make lint + out$> make style Good first contributions ~~~~~~~~~~~~~~~~~~~~~~~~ You are welcome to contribute wherever in the code you want to, of course, but -we recommend taking a look at the "Good first contribution" label into the issues and -pick one. We would love to mentor you! +we recommend taking a look at the "Good first contribution" label into the +issues and pick one. We would love to mentor you! Doc ~~~ -Review the parts of the documentation regarding the new changes and -update it if it's needed. +Review the parts of the documentation regarding the new changes and update it +if it's needed. Pull requests ~~~~~~~~~~~~~ -We use `GitHub pull requests -`_ to accept the -contributions. +We use `GitHub pull requests `_ +to accept the contributions. A friendly reminder! We'd love to have a previous discussion about the best way to implement the feature/bug you are contributing with. This is a good way to @@ -251,13 +250,13 @@ you are ready to start coding (yay!). We have two options here: Please follow the next rules for the commit messages: -- It should include a reference to the issue ID in the first line of the - commit, **and** a brief description of the issue, so everybody knows what - this ID actually refers to without wasting to much time on following the - link to the issue. +- It should include a reference to the issue ID in the first line of the commit, + **and** a brief description of the issue, so everybody knows what this ID + actually refers to without wasting to much time on following the link to the + issue. -- It should provide enough information for a reviewer to understand the - changes and their relation to the rest of the code. +- It should provide enough information for a reviewer to understand the changes + and their relation to the rest of the code. A good example: @@ -273,6 +272,83 @@ A (really) bad example: Fixes #190 +Development cycle +----------------- + +Our development cycle is straightforward, we define a roadmap with milestones +for releases, and features that we want to include in these releases. The +roadmap is not public at the moment, but it's a committed project in our +community and we are working to make parts of it public in a way that can be +beneficial for everyone. Whenever a new release is close to be launched, we'll +announce it and detail what has changed since the latest version. +The channels we'll use to announce new releases are still being discussed, but +for now you can `follow us `_ on Twitter! + +Branch model +~~~~~~~~~~~~ + +There are two main branches in the repository: + +- ``master`` + + - This is the development branch. + - Next release is going to be developed here. For example, if the current + latest release version is r1.0.3, the master branch version will point to + r1.1.0 (or r2.0.0). + - You should expect this branch to be updated very frequently. + - Even though we are always doing our best to not push code that breaks + things, is more likely to eventually push code that breaks something... + we will fix it ASAP, promise :). + - This should not be considered as a stable branch to use in production + environments. + - The API of the SDK could change without prior notice. + +- ``stable`` + + - This is our stable release branch. + - It's always synchronized with the latest distributed package, as for now, + the package you can download from pip. + - The code in this branch is well tested and should be free of errors + (unfortunately sometimes it's not). + - This is a stable branch (as the name suggest), meaning that you can expect + stable software ready for production environments. + - All the tags from the release versions are created from this branch. + +Release cycle +~~~~~~~~~~~~~ + +From time to time, we will release brand new versions of the QISKit SDK. These +are well-tested versions of the software. + +When the time for a new release has come, we will: + +1. Merge the ``master`` branch with the ``stable`` branch. +2. Create a new tag with the version number in the ``stable`` branch. +3. Crate and distribute the pip package. +4. Change the ``master`` version to the next release version. +5. Announce the new version to the world! + +The ``stable`` branch should only receive changes in the form of bug fixes, so the +third version number (the maintenance number: [major].[minor].[maintenance]) +will increase on every new change. + +What version should I use: development or stable? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +It depends on your needs as a user. + +If you want to use QISKit for building Apps which goal is to run Quantum +programs, we encourage you to use the latest released version, installing it via +Pip. + +.. code:: sh + + $ pip install qiskit` + +If you found out that the release version doesn't fit your needs, and you are +thinking about extending the functionality of the SDK, you are more likely to +use the ``master`` branch and thinking seriously about contributing with us :) + Documentation ------------- @@ -298,5 +374,5 @@ All platforms: .. code:: sh - $> cd out - doc$> make doc + $> cd out + doc$> make doc diff --git a/DEVELOPMENT_CYCLE.md b/DEVELOPMENT_CYCLE.md deleted file mode 100644 index feda96074bfa..000000000000 --- a/DEVELOPMENT_CYCLE.md +++ /dev/null @@ -1,47 +0,0 @@ -# DEVELOPMENT CYCLE -Our development cycle is straightforward, we define a roadmap with milestones for releases, and features that we want -to include in these releases. The roadmap is not public at the moment, but it’s a committed project in our community and we are working to make parts of it public in a way that can be beneficial for everyone. Whenever a new release is close to be launched, we'll announce it and detail what has changed since the latest version. -The channels we'll use to announce new releases are still being discussed, but for now you can [follow us](https://twitter.com/qiskit) on Twitter! - -## BRANCH MODEL -There are two main branches in the repository: - -* `master` - * This is the development branch. - * Next release is going to be developed here. For example, if the current latest release version is r1.0.3, the - master branch version will point to r1.1.0 (or r2.0.0). - * You should expect this branch to be updated very frequently. - * Even though we are always doing our best to not push code that breaks things, is more likely to eventually push - code that breaks something... we will fix it ASAP, promise :). - * This should not be considered as a stable branch to use in production environments. - * The API of the SDK could change without prior notice. - -* `stable` - * This is our stable release branch. - * It's always synchronized with the latest distributed package, as for now, the package you can download from pip. - * The code in this branch is well tested and should be free of errors (unfortunately sometimes it's not). - * This is a stable branch (as the name suggest), meaning that you can expect stable software ready for production - environments. - * All the tags from the release versions are created from this branch. - -## RELEASE CYCLE -From time to time, we will release brand new versions of the QISKit SDK. These are well-tested versions of the software. -When the time for a new release has come, we will: -1. Merge the `master` branch with the `stable` branch. -2. Create a new tag with the version number in the `stable` branch. -3. Crate and distribute the pip package. -4. Change the `master` version to the next release version. -5. Announce the new version to the world! - -The `stable` branch should only receive changes in the form of bug fixes, so the third version number (the maintenance -number: ..) will increase on every new change. - -## WHAT VERSION SHOULD I USE: DEVELOPMENT OR STABLE? -It depends on your needs as a user. -If you want to use QISKit for building Apps which goal is to run Quantum programs, we encourage you to use the latest -released version, installing it via Pip. - -`$ pip install qiskit` - -If you found out that the release version doesn't fit your needs, and you are thinking about extending the functionality -of the SDK, you are more likely to use the `master` branch and thinking seriously about contributing with us :) From cc30e61800b09929dc37d031fa7c5a55d4217fa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abd=C3=B3n=20Rodr=C3=ADguez=20Davila?= Date: Wed, 23 May 2018 17:44:15 +0200 Subject: [PATCH 10/22] [skip ci] Update code owners to allow automatic-reviews (#499) --- .github/CODEOWNERS | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c1523b328059..45b5c84bf5cc 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,14 +1,23 @@ -# Where component owners are known, add them here. +# Default owners for everything in the repo. Further rules in the file may +# (and should) override the notifications they get - but still be able to act +# as code owners if needed +* @jaygambetta @ismaelfaro -qiskit/core/* @ewinston @awcross1 @pacomf @jaygambetta @ismaelfaro -qiskit/core/simulators/* @ewinston @chriseclectic -qiskit/doc/* @ewinston @pacomf +# Files on root directory. This pattern is actually the one that will apply +# unless specialized by a later rule +/* @ajavadia @ewinston @atilag @diego-plan9 -qiskit/tools/qcvv/* @chriseclectic -qiskit/tools/qi/* @chriseclectic -qiskit/tools/apps/* @antoniomezzacapo +# Individual folders on root directory +/cmake @atilag +/doc @diego-plan9 +/examples @jaygambetta +/src @chriseclectic -# other repository - -qiskit-tutorial @ewinston @awcross1 @jaygambetta @antoniomezzacapo -qiskit-api-py @pacomf +# qiskit folder +qiskit/* @ajavadia @ewinston @awcross1 @1ucian0 @atilag @diego-plan9 @delapuente +qiskit/**/*.py @ajavadia @ewinston @atilag @diego-plan9 +qiskit/mapper/* @ajavadia +qiskit/qasm/* @1ucian0 +qiskit/tools/qcvv/* @chriseclectic +qiskit/tools/qi/* @chriseclectic +qiskit/tools/apps/* @antoniomezzacapo From cc16f60927e967188368e8963b44e904caf16a86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20M=2E=20Rodr=C3=ADguez?= Date: Thu, 24 May 2018 13:01:55 +0200 Subject: [PATCH 11/22] Tune CODEOWNERS to prevent notifications (#502) Revise the `CODEOWNERS` file, as the previous set of rules were causing extra notifications and issues with the defined set of code owners. The rules do not "inherit" codeowners from previous rules - the file has been rewritten to explicitly list codeowners for each section. --- .github/CODEOWNERS | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 45b5c84bf5cc..41eea816b48e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,23 +1,22 @@ -# Default owners for everything in the repo. Further rules in the file may -# (and should) override the notifications they get - but still be able to act -# as code owners if needed -* @jaygambetta @ismaelfaro +# This file defines the persons that will be assigned as reviewers for PRs that +# modify a particular file in the repo. Please note it is just a convention +# for the GitHub interface, and any member of the QISKit team can (and should!) +# review as well. -# Files on root directory. This pattern is actually the one that will apply -# unless specialized by a later rule -/* @ajavadia @ewinston @atilag @diego-plan9 +# Real code owners. +#* @jaygambetta @ismaelfaro + +# Generic rule for the repository. This pattern is actually the one that will +# apply unless specialized by a later rule +* @ajavadia @ewinston @atilag @delapuente @diego-plan9 # Individual folders on root directory -/cmake @atilag -/doc @diego-plan9 -/examples @jaygambetta -/src @chriseclectic +/cmake @ajavadia @atilag @diego-plan9 +/doc @jaygambetta @ajavadia @atilag @diego-plan9 +/examples @jaygambetta @ajavadia @atilag @diego-plan9 +/src @chriseclectic @ajavadia @atilag @diego-plan9 -# qiskit folder -qiskit/* @ajavadia @ewinston @awcross1 @1ucian0 @atilag @diego-plan9 @delapuente -qiskit/**/*.py @ajavadia @ewinston @atilag @diego-plan9 -qiskit/mapper/* @ajavadia -qiskit/qasm/* @1ucian0 -qiskit/tools/qcvv/* @chriseclectic -qiskit/tools/qi/* @chriseclectic -qiskit/tools/apps/* @antoniomezzacapo +# qiskit folders +qiskit/qasm/* @1ucian0 @ajavadia @ewinston @atilag @delapuente @diego-plan9 +qiskit/tools/* @antoniomezzacapo @chriseclectic @ajavadia @ewinston @atilag @delapuente @diego-plan9 +qiskit/schemas/* @jaygambetta @ajavadia @ewinston @atilag @delapuente @diego-plan9 From 6f76c88bdb67e3ecfdeeaa7c02d1be89d155d56c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20M=2E=20Rodr=C3=ADguez?= Date: Thu, 24 May 2018 13:30:11 +0200 Subject: [PATCH 12/22] Fix #479: Raise IndexError during Register.__getitem__ (#491) * Raise IndexError during Register.__getitem__ Update `Register.__getitem__` to conform to the Python convention and raise a subclass of `IndexError` for identifying the end of the sequence when using it in a `for` loop. The exception raised is also a subclass of `QISKitError`, for consistency with our current exception policy. * Add __repr__ to Register, trim subclasses Add a `__repr__` method to `Register` that extends the previously existing `__str__` method, providing a valid Python string that can be used for recreating the object (fixing the argument order in the process). Remove methods from subclasses that are already provided by the parent class. * Add __iter__ for Register Add an `__iter__` method for providing cleaner access to iterating over the elements of a `Register` and its subclasses via an iterator instead of relying on `__getitem__`. --- qiskit/_classicalregister.py | 8 -------- qiskit/_qiskiterror.py | 5 +++++ qiskit/_quantumregister.py | 8 -------- qiskit/_register.py | 34 +++++++++++++++++++++++++++------- 4 files changed, 32 insertions(+), 23 deletions(-) diff --git a/qiskit/_classicalregister.py b/qiskit/_classicalregister.py index 1c62a48d7de9..3f2004c8375c 100644 --- a/qiskit/_classicalregister.py +++ b/qiskit/_classicalregister.py @@ -34,11 +34,3 @@ class ClassicalRegister(Register): def qasm(self): """Return OPENQASM string for this register.""" return "creg %s[%d];" % (self.name, self.size) - - def __str__(self): - """Return a string representing the register.""" - return "ClassicalRegister(%s,%d)" % (self.name, self.size) - - def __len__(self): - """Return a int representing the size.""" - return self.size diff --git a/qiskit/_qiskiterror.py b/qiskit/_qiskiterror.py index 1442ae3ce75c..99979592eae1 100644 --- a/qiskit/_qiskiterror.py +++ b/qiskit/_qiskiterror.py @@ -31,3 +31,8 @@ def __init__(self, *message): def __str__(self): """Return the message.""" return repr(self.message) + + +class QISKitIndexError(QISKitError, IndexError): + """Raised when a sequence subscript is out of range.""" + pass diff --git a/qiskit/_quantumregister.py b/qiskit/_quantumregister.py index 5eb59e1b2bc7..566a4bb5e31a 100644 --- a/qiskit/_quantumregister.py +++ b/qiskit/_quantumregister.py @@ -33,11 +33,3 @@ class QuantumRegister(Register): def qasm(self): """Return OPENQASM string for this register.""" return "qreg %s[%d];" % (self.name, self.size) - - def __str__(self): - """Return a string representing the register.""" - return "QuantumRegister(%s,%d)" % (self.name, self.size) - - def __len__(self): - """Return a int representing the size.""" - return self.size diff --git a/qiskit/_register.py b/qiskit/_register.py index 7b70e7d38294..af4fa6557528 100644 --- a/qiskit/_register.py +++ b/qiskit/_register.py @@ -23,7 +23,7 @@ import itertools import warnings -from ._qiskiterror import QISKitError +from ._qiskiterror import QISKitError, QISKitIndexError logger = logging.getLogger(__name__) @@ -69,9 +69,10 @@ def __init__(self, size, name=None): if size <= 0: raise QISKitError("register size must be positive") - def __str__(self): - """Return a string representing the register.""" - return "Register(%s,%d)" % (self.name, self.size) + def __repr__(self): + """Return the official string representing the register.""" + return "%s(%d, '%s')" % (self.__class__.__qualname__, + self.size, self.name) def __len__(self): """Return register size""" @@ -80,11 +81,30 @@ def __len__(self): def check_range(self, j): """Check that j is a valid index into self.""" if j < 0 or j >= self.size: - raise QISKitError("register index out of range") + raise QISKitIndexError("register index out of range") def __getitem__(self, key): - """Return tuple (self, key) if key is valid.""" + """ + Arg: + key (int): index of the bit/qubit to be retrieved. + + Returns: + tuple[Register, int]: a tuple in the form `(self, key)`. + + Raises: + QISKitError: if the `key` is not an integer. + QISKitIndexError: if the `key` is not in the range + `(0, self.size)`. + """ if not isinstance(key, int): raise QISKitError("expected integer index into register") self.check_range(key) - return (self, key) + return self, key + + def __iter__(self): + """ + Returns: + iterator: an iterator over the bits/qubits of the register, in the + form `tuple (Register, int)`. + """ + return zip([self]*self.size, range(self.size)) From 77e33308a42cdf9fc9b9da6e293f85232b62685c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20M=2E=20Rodr=C3=ADguez?= Date: Thu, 24 May 2018 13:31:07 +0200 Subject: [PATCH 13/22] Rename camel_case_to_snake_case, uuids (#490) Rename `_snake_case_to_camel_case()` to `_camel_case_to_snake_case()` in order to match its functionality. Unify the way random identifiers are generated, using `uuid4()` instead of manually generated random strings. --- qiskit/_compiler.py | 8 +++----- qiskit/_quantumjob.py | 11 +++-------- qiskit/_quantumprogram.py | 6 ++---- qiskit/_util.py | 13 ++++++++++--- qiskit/backends/ibmq/ibmqbackend.py | 8 ++++---- qiskit/backends/ibmq/ibmqprovider.py | 4 ++-- test/python/_random_qasm_generator.py | 5 ++--- tools/random_qasm_generator.py | 11 +++++------ 8 files changed, 31 insertions(+), 35 deletions(-) diff --git a/qiskit/_compiler.py b/qiskit/_compiler.py index 4bb0448a19f0..13fe093c52ad 100644 --- a/qiskit/_compiler.py +++ b/qiskit/_compiler.py @@ -19,9 +19,9 @@ """Tools for compiling a batch of quantum circuits.""" import logging -import random -import string import copy +import uuid + import numpy as np import scipy.sparse as sp import scipy.sparse.csgraph as cs @@ -78,9 +78,7 @@ def compile(circuits, backend, backend_name = backend_conf['name'] qobj = {} - if not qobj_id: - qobj_id = "".join([random.choice(string.ascii_letters + string.digits) - for n in range(30)]) + qobj_id = qobj_id or str(uuid.uuid4()) qobj['id'] = qobj_id qobj['config'] = {'max_credits': max_credits, 'shots': shots, diff --git a/qiskit/_quantumjob.py b/qiskit/_quantumjob.py index eb7441a0861e..b0507798dd17 100644 --- a/qiskit/_quantumjob.py +++ b/qiskit/_quantumjob.py @@ -17,8 +17,7 @@ # ============================================================================= """Quantum Job class""" -import random -import string +import uuid # stable modules from ._quantumcircuit import QuantumCircuit @@ -64,7 +63,7 @@ def __init__(self, circuits, backend, if names is None: self.names = [] for _ in range(len(self.circuits)): - self.names.append(self._generate_job_id(length=10)) + self.names.append(str(uuid.uuid4())) elif isinstance(names, list): self.names = names else: @@ -132,14 +131,10 @@ def _create_qobj(self, circuits, circuit_config, backend, seed, } circuit_records.append(record) - return {'id': self._generate_job_id(length=10), + return {'id': str(uuid.uuid4()), 'config': { 'max_credits': resources['max_credits'], 'shots': shots, 'backend_name': backend.configuration['name'] }, 'circuits': circuit_records} - - def _generate_job_id(self, length=10): - return ''.join([random.choice( - string.ascii_letters + string.digits) for i in range(length)]) diff --git a/qiskit/_quantumprogram.py b/qiskit/_quantumprogram.py index 3dbf1328c1a9..2f7ee1d4225b 100644 --- a/qiskit/_quantumprogram.py +++ b/qiskit/_quantumprogram.py @@ -23,8 +23,7 @@ import json import logging import os -import random -import string +import uuid import warnings import qiskit.wrapper @@ -453,8 +452,7 @@ def load_qasm_text(self, qasm_string, name=None, node_circuit = Qasm(data=qasm_string).parse() # Node (AST) if not name: # Get a random name if none is given - name = "".join([random.choice(string.ascii_letters + string.digits) - for n in range(10)]) + name = str(uuid.uuid4()) logger.info("circuit name: %s", name) logger.info("******************************") logger.info(node_circuit.qasm()) diff --git a/qiskit/_util.py b/qiskit/_util.py index d12920aeb686..75fc3567f512 100644 --- a/qiskit/_util.py +++ b/qiskit/_util.py @@ -111,9 +111,16 @@ def _enable_deprecation_warnings(): warnings._add_filter(*deprecation_filter, append=False) -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) +def _camel_case_to_snake_case(identifier): + """Return a `snake_case` string from a `camelCase` string. + + Args: + identifier (str): a `camelCase` string. + + Returns: + str: a `snake_case` string. + """ + string_1 = FIRST_CAP_RE.sub(r'\1_\2', identifier) return ALL_CAP_RE.sub(r'\1_\2', string_1).lower() diff --git a/qiskit/backends/ibmq/ibmqbackend.py b/qiskit/backends/ibmq/ibmqbackend.py index f99a8c0e6e86..7bf4bce1f50f 100644 --- a/qiskit/backends/ibmq/ibmqbackend.py +++ b/qiskit/backends/ibmq/ibmqbackend.py @@ -20,7 +20,7 @@ """ import logging -from qiskit._util import _snake_case_to_camel_case +from qiskit._util import _camel_case_to_snake_case from qiskit.backends import BaseBackend from qiskit.backends.ibmq.ibmqjob import IBMQJob @@ -44,7 +44,7 @@ def __init__(self, configuration, api=None): if self._configuration: configuration_edit = {} for key, vals in self._configuration.items(): - new_key = _snake_case_to_camel_case(key) + new_key = _camel_case_to_snake_case(key) configuration_edit[new_key] = vals self._configuration = configuration_edit # FIXME: This is a hack to make sure that the @@ -87,7 +87,7 @@ def calibration(self): calibrations_edit = {} for key, vals in calibrations.items(): - new_key = _snake_case_to_camel_case(key) + new_key = _camel_case_to_snake_case(key) calibrations_edit[new_key] = vals return calibrations_edit @@ -115,7 +115,7 @@ def parameters(self): parameters_edit = {} for key, vals in parameters.items(): - new_key = _snake_case_to_camel_case(key) + new_key = _camel_case_to_snake_case(key) parameters_edit[new_key] = vals return parameters_edit diff --git a/qiskit/backends/ibmq/ibmqprovider.py b/qiskit/backends/ibmq/ibmqprovider.py index a44c6592ddee..e266aa1fa0f8 100644 --- a/qiskit/backends/ibmq/ibmqprovider.py +++ b/qiskit/backends/ibmq/ibmqprovider.py @@ -18,7 +18,7 @@ """Provider for remote IbmQ backends.""" from IBMQuantumExperience import IBMQuantumExperience -from qiskit._util import _snake_case_to_camel_case +from qiskit._util import _camel_case_to_snake_case from qiskit.backends.baseprovider import BaseProvider from qiskit.backends.ibmq.ibmqbackend import IBMQBackend @@ -117,7 +117,7 @@ def _parse_backend_configuration(cls, config): } for key in config.keys(): - new_key = _snake_case_to_camel_case(key) + new_key = _camel_case_to_snake_case(key) if new_key not in ['id', 'serial_number', 'topology_id', 'status']: edited_config[new_key] = config[key] diff --git a/test/python/_random_qasm_generator.py b/test/python/_random_qasm_generator.py index 28309ac73d7f..d03c7ca896f4 100644 --- a/test/python/_random_qasm_generator.py +++ b/test/python/_random_qasm_generator.py @@ -17,7 +17,7 @@ # ============================================================================= import random -import string +import uuid import numpy @@ -69,8 +69,7 @@ def add_circuits(self, n_circuits, do_measure=True): 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)) + circuit_name = str(uuid.uuid4()) self.circuit_name_list.append(circuit_name) n_qubits = self.n_qubit_list[i] depth = self.depth_list[i] diff --git a/tools/random_qasm_generator.py b/tools/random_qasm_generator.py index 83e8177d661d..050e58f45243 100755 --- a/tools/random_qasm_generator.py +++ b/tools/random_qasm_generator.py @@ -23,12 +23,11 @@ # (CX and U3 gates), 16 Qubits, and a seed of 169 # ./random_qasm_generator.py -s 169 -d 100 -q 16 > circuit.qasm +import argparse import os -import sys import random -import string -import argparse -import numpy +import sys +import uuid try: import qiskit @@ -38,6 +37,7 @@ from qiskit import QuantumProgram + class RandomQasmGenerator(): """ Generate circuits with random operations for profiling. @@ -72,8 +72,7 @@ def create_circuit(self, do_measure=True): Returns: A string representing the QASM circuit """ - circuit_name = ''.join(numpy.random.choice( - list(string.ascii_letters + string.digits))) + circuit_name = str(uuid.uuid4()) circuit = self.quantum_program.create_circuit(circuit_name, [self.quantum_register], [self.classical_register]) From 2a31aa0d8fe4d0f534820996499de1cbab2cced7 Mon Sep 17 00:00:00 2001 From: Paul Nation Date: Thu, 24 May 2018 11:11:36 -0400 Subject: [PATCH 14/22] Add note about package downgrades. (#505) --- doc/install.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/install.rst b/doc/install.rst index b8dfd529301a..f1938c129985 100644 --- a/doc/install.rst +++ b/doc/install.rst @@ -30,6 +30,9 @@ package manager): This will install the latest stable release along with all the dependencies. +.. note:: + Some packages may be downgraded to meet requirements. + .. _qconfig-setup: 3. Configure your API token and QE credentials From 63c7065155f4357f5bde128c2c3db4e35ed1fa76 Mon Sep 17 00:00:00 2001 From: Eddie Schoute Date: Fri, 25 May 2018 03:46:49 -0400 Subject: [PATCH 15/22] Changed deepcopy to copy in mapper (#485) --- qiskit/mapper/_mapping.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/qiskit/mapper/_mapping.py b/qiskit/mapper/_mapping.py index 5e09d8478bdb..adaa649ed98f 100644 --- a/qiskit/mapper/_mapping.py +++ b/qiskit/mapper/_mapping.py @@ -19,7 +19,6 @@ """ Layout module to assist with mapping circuit qubits onto physical qubits. """ -import copy import logging import pprint import sys @@ -211,8 +210,8 @@ def layer_permutation(layer_partition, layout, qubit_subset, coupling, trials, for trial in range(trials): logger.debug("layer_permutation: trial %s", trial) - trial_layout = copy.deepcopy(layout) - rev_trial_layout = copy.deepcopy(rev_layout) + trial_layout = layout.copy() + rev_trial_layout = rev_layout.copy() # SWAP circuit constructed this trial trial_circ = DAGCircuit() trial_circ.add_qreg('q', layout_max_index) @@ -256,10 +255,10 @@ def layer_permutation(layer_partition, layout, qubit_subset, coupling, trials, # Are the qubits available? if e[0] in qubit_set and e[1] in qubit_set: # Try this edge to reduce the cost - new_layout = copy.deepcopy(trial_layout) + new_layout = trial_layout.copy() new_layout[rev_trial_layout[e[0]]] = e[1] new_layout[rev_trial_layout[e[1]]] = e[0] - rev_new_layout = copy.deepcopy(rev_trial_layout) + rev_new_layout = rev_trial_layout.copy() rev_new_layout[e[0]] = rev_trial_layout[e[1]] rev_new_layout[e[1]] = rev_trial_layout[e[0]] # Compute the objective function @@ -482,7 +481,7 @@ def swap_mapper(circuit_graph, coupling_graph, zip(circuit_graph.get_qubits(), qubit_subset)} # Find swap circuit to preceed to each layer of input circuit - layout = copy.deepcopy(initial_layout) + layout = initial_layout.copy() layout_max_index = max(map(lambda x: x[1]+1, layout.values())) # Construct an empty DAGCircuit with one qreg "q" From cde20b7c94ce996874e35bc39c40110d367051e2 Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Fri, 25 May 2018 04:25:43 -0400 Subject: [PATCH 16/22] fix deprecated name for ibmqx_hpc_qasm_simulator (#506) * fix deprecated simulator name * add new contributors --- CONTRIBUTORS.md | 2 ++ qiskit/backends/ibmq/ibmqprovider.py | 9 ++------- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index efe05315f00c..b88a7414d864 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -14,11 +14,13 @@ involved in the project: * Jay Gambetta * Juan Gomez * Ali Javadi-Abhari +* Peng Liu * Yunho Maeng * Paco Martin * Antonio Mezzacapo * Diego Moreda * Jesus Perez +* Marco Pistoia * Russell Rundle * Todd Tilma * John Smolin diff --git a/qiskit/backends/ibmq/ibmqprovider.py b/qiskit/backends/ibmq/ibmqprovider.py index e266aa1fa0f8..53df8a4477bc 100644 --- a/qiskit/backends/ibmq/ibmqprovider.py +++ b/qiskit/backends/ibmq/ibmqprovider.py @@ -50,17 +50,12 @@ def available_backends(self, filters=None): return list(backends.values()) def aliased_backend_names(self): - return { - # TODO: Review the comment below. Is still true? - # FIXME: uncomment after API fix: online simulator names should change - # 'ibmq_qasm_simulator': ['ibmq_qasm_simulator', - # 'ibmq_qasm_simulator_hpc'] - } + return {} def deprecated_backend_names(self): return { 'ibmqx_qasm_simulator': 'ibmq_qasm_simulator', - 'ibmqx_qasm_simulator_hpc': 'ibmq_qasm_simulator', + 'ibmqx_hpc_qasm_simulator': 'ibmq_qasm_simulator', 'real': 'ibmqx1' } From 32fcf19dba2bf5be3e2c7d70cb732b3d75c82061 Mon Sep 17 00:00:00 2001 From: alfrisch Date: Fri, 25 May 2018 17:16:42 +0200 Subject: [PATCH 17/22] updated README.md for version >0.5.0 (#508) * replacing set_api() with register() updating link to getting_started.ipnyb * adding me to list of contributors * correcting updated link and pointing to QISKit/qiskit-tutorial now * fixed indentation --- CONTRIBUTORS.md | 1 + README.md | 16 +++++++--------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index b88a7414d864..03dd0d262009 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -11,6 +11,7 @@ involved in the project: * Vincent Dwyer * Mark Everitt * Ismael Faro +* Albert Frisch * Jay Gambetta * Juan Gomez * Ali Javadi-Abhari diff --git a/README.md b/README.md index 5364155acc9b..1a5fc1f1af52 100644 --- a/README.md +++ b/README.md @@ -151,18 +151,16 @@ your IBM Q Experience account: `config` variable with the values you can find on your IBM Q account page. -Once the `Qconfig.py` file is set up, you have to move it under the same directory/folder where your program/tutorial resides, so it can be imported and be used to authenticate with the `set_api()` function. For example: +Once the `Qconfig.py` file is set up, you have to move it under the same directory/folder where your program/tutorial resides, so it can be imported and be used to authenticate with the `register()` function. For example: ```python -from qiskit import QuantumProgram +from qiskit import register import Qconfig -# Creating Programs create your first QuantumProgram object instance. -qp = QuantumProgram() -qp.set_api(Qconfig.APItoken, Qconfig.config["url"], - hub=Qconfig.config["hub"], - group=Qconfig.config["group"], - project=Qconfig.config["project"]) +register(Qconfig.APItoken, Qconfig.config["url"], + hub=Qconfig.config["hub"], + group=Qconfig.config["group"], + project=Qconfig.config["project"]) ``` For more details on this and more information see @@ -174,7 +172,7 @@ For more details on this and more information see Now you're set up and ready to check out some of the other examples from our [Tutorial](https://github.com/QISKit/qiskit-tutorial) repository. Start with the [index tutorial](https://github.com/QISKit/qiskit-tutorial/blob/master/index.ipynb) and then go to -the [‘Getting Started’ example](https://github.com/QISKit/qiskit-tutorial/blob/002d054c72fc59fc5009bb9fa0ee393e15a69d07/1_introduction/getting_started.ipynb). +the [‘Getting Started’ example](https://github.com/QISKit/qiskit-tutorial/blob/master/reference/tools/getting_started.ipynb). If you already have [Jupyter Notebooks installed](https://jupyter.readthedocs.io/en/latest/install.html), you can copy and modify the notebooks to create your own experiments. From fd87a76c3c6a5dbfd8e944a694a354c1394ad2c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20M=2E=20Rodr=C3=ADguez?= Date: Sat, 26 May 2018 18:16:53 +0200 Subject: [PATCH 18/22] Replace "QI Software Kit" with "QI Science Kit" (#510) --- README.md | 4 ++-- doc/conf.py | 2 +- doc/index.rst | 2 +- doc/ja/index.rst | 2 +- doc/ko/README.md | 2 +- doc/zh/README.md | 2 +- src/qasm-simulator-cpp/README.md | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 1a5fc1f1af52..9bb60af1771b 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -# Quantum Information Software Kit (QISKit) +# Quantum Information Science Kit (QISKit) [![PyPI](https://img.shields.io/pypi/v/qiskit.svg)](https://pypi.python.org/pypi/qiskit) [![Build Status](https://travis-ci.org/QISKit/qiskit-sdk-py.svg?branch=master)](https://travis-ci.org/QISKit/qiskit-sdk-py) -The Quantum Information Software Kit (**QISKit** for short) is a software development kit (SDK) for +The Quantum Information Science Kit (**QISKit** for short) is a software development kit (SDK) for working with [OpenQASM](https://github.com/QISKit/qiskit-openqasm) and the [IBM Q Experience (QX)](https://quantumexperience.ng.bluemix.net/). diff --git a/doc/conf.py b/doc/conf.py index bbbed6bb115e..87307ffec00f 100755 --- a/doc/conf.py +++ b/doc/conf.py @@ -79,7 +79,7 @@ # Add description html_context = { - 'description': 'Quantum Information Software Kit' + 'description': 'Quantum Information Science Kit' } # The version info for the project you're documenting, acts as replacement for diff --git a/doc/index.rst b/doc/index.rst index b54572bb72ff..9c0f828bb086 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -7,7 +7,7 @@ QISKit Documentation ==================== -Quantum Information Software Kit (QISKit), SDK Python version for working +Quantum Information Science Kit (QISKit), SDK Python version for working with `OpenQASM `_ and the IBM Q experience (QX). diff --git a/doc/ja/index.rst b/doc/ja/index.rst index fe2b7d2a6a48..c9acb96206aa 100644 --- a/doc/ja/index.rst +++ b/doc/ja/index.rst @@ -7,7 +7,7 @@ QISKit マニュアル ================= -Quantum Information Software Kit (QISKit, 量子情報ソフトウェアキット)は +Quantum Information Science Kit (QISKit, 量子情報ソフトウェアキット)は `OpenQASM `_ とIBM Q Experience(QX) を利用してプログラミングをするためのPythonソフトウェア開発キット(SDK)です。 diff --git a/doc/ko/README.md b/doc/ko/README.md index 9189ed924db6..f19371c9715b 100644 --- a/doc/ko/README.md +++ b/doc/ko/README.md @@ -1,4 +1,4 @@ -# Quantum Information Software Kit (QISKit) +# Quantum Information Science Kit (QISKit) [![PyPI](https://img.shields.io/pypi/v/qiskit.svg)](https://pypi.python.org/pypi/qiskit) [![Build Status](https://travis-ci.org/QISKit/qiskit-sdk-py.svg?branch=master)](https://travis-ci.org/QISKit/qiskit-sdk-py) diff --git a/doc/zh/README.md b/doc/zh/README.md index 85017a65098f..835048feea28 100644 --- a/doc/zh/README.md +++ b/doc/zh/README.md @@ -1,4 +1,4 @@ -# Quantum Information Software Kit (QISKit) +# Quantum Information Science Kit (QISKit) [![PyPI](https://img.shields.io/pypi/v/qiskit.svg)](https://pypi.python.org/pypi/qiskit) [![Build Status](https://travis-ci.org/QISKit/qiskit-sdk-py.svg?branch=master)](https://travis-ci.org/QISKit/qiskit-sdk-py) diff --git a/src/qasm-simulator-cpp/README.md b/src/qasm-simulator-cpp/README.md index 587477cb2757..5742d45ccbcf 100644 --- a/src/qasm-simulator-cpp/README.md +++ b/src/qasm-simulator-cpp/README.md @@ -11,7 +11,7 @@ Copyright (c) 2017 IBM Corporation. All Rights Reserved. ### Description -*QASM Simulator* is a quantum circuit simulator written in C++ that includes a variety of realistic circuit level noise models. The simulator may be run as a command line application to evaluate quantum programs specified by a *Quantum program OBJect (__QObj__)*. It may also be used as a local backend in the *Quantum Information Software Kit ([__QISKit__](https://www.qiskit.org))* [Python SDK](https://github.com/QISKit/qiskit-sdk-py). +*QASM Simulator* is a quantum circuit simulator written in C++ that includes a variety of realistic circuit level noise models. The simulator may be run as a command line application to evaluate quantum programs specified by a *Quantum program OBJect (__QObj__)*. It may also be used as a local backend in the *Quantum Information Science Kit ([__QISKit__](https://www.qiskit.org))* [Python SDK](https://github.com/QISKit/qiskit-sdk-py). ## Contents From 3b653f6d34d916b831eb385347dad77d1c1dd4c1 Mon Sep 17 00:00:00 2001 From: Ali Javadi-Abhari Date: Mon, 28 May 2018 09:29:46 -0400 Subject: [PATCH 19/22] adding `load_qasm` and default `url` to wrapper (#512) * Adding load_qasm_* methods to wrapper * Adding load_qasm_* to __init__ and modifying quantumprogram to point to wrapper * Passing default url to wrapper.register * Adding some tests for load_qasm_* functions * Adding a simple example --- examples/python/load_qasm.py | 25 ++++++ qiskit/__init__.py | 3 +- qiskit/_quantumprogram.py | 32 ++------ qiskit/wrapper/__init__.py | 3 +- qiskit/wrapper/_wrapper.py | 59 +++++++++++++- test/python/test_load_qasm.py | 144 ++++++++++++++++++++++++++++++++++ 6 files changed, 239 insertions(+), 27 deletions(-) create mode 100644 examples/python/load_qasm.py create mode 100644 test/python/test_load_qasm.py diff --git a/examples/python/load_qasm.py b/examples/python/load_qasm.py new file mode 100644 index 000000000000..2d4d906aaf67 --- /dev/null +++ b/examples/python/load_qasm.py @@ -0,0 +1,25 @@ +""" +Example on how to use: load_qasm_file +If you want to use your local cloned repository intead of the one installed via pypi, +you have to run like this: + examples/python$ PYTHONPATH=$PYTHONPATH:../.. python load_qasm.py +""" +from qiskit.wrapper import load_qasm_file +from qiskit import QISKitError, available_backends, execute +try: + qc = load_qasm_file("../qasm/entangled_registers.qasm") + + # See a list of available local simulators + print("Local backends: ", available_backends({'local': True})) + + # Compile and run the Quantum circuit on a local simulator backend + job_sim = execute(qc, "local_qasm_simulator") + sim_result = job_sim.result() + + # Show the results + print("simulation: ", sim_result) + print(sim_result.get_counts(qc)) + +except QISKitError as ex: + print('There was an internal QISKit error. Error = {}'.format(ex)) + diff --git a/qiskit/__init__.py b/qiskit/__init__.py index 056ec2dd9f6f..93c7e292e309 100644 --- a/qiskit/__init__.py +++ b/qiskit/__init__.py @@ -41,7 +41,8 @@ from ._quantumjob import QuantumJob from ._quantumprogram import QuantumProgram from ._result import Result -from .wrapper._wrapper import available_backends, execute, register, get_backend, compile +from .wrapper._wrapper import (available_backends, execute, register, get_backend, compile, + load_qasm_string, load_qasm_file) # Import the wrapper, to make it available when doing "import qiskit". from . import wrapper diff --git a/qiskit/_quantumprogram.py b/qiskit/_quantumprogram.py index 2f7ee1d4225b..33b6f3232763 100644 --- a/qiskit/_quantumprogram.py +++ b/qiskit/_quantumprogram.py @@ -22,8 +22,6 @@ import itertools import json import logging -import os -import uuid import warnings import qiskit.wrapper @@ -36,7 +34,6 @@ from ._quantumregister import QuantumRegister from .mapper import coupling_dict2list from .qasm import Qasm -from .unroll import CircuitBackend, Unroller logger = logging.getLogger(__name__) @@ -422,17 +419,10 @@ def load_qasm_file(self, qasm_file, name=None, Raises: QISKitError: if the file cannot be read. """ - if not os.path.exists(qasm_file): - raise QISKitError('qasm file "{0}" not found'.format(qasm_file)) - if not name: - name = os.path.splitext(os.path.basename(qasm_file))[0] - node_circuit = Qasm(filename=qasm_file).parse() # Node (AST) - logger.info("circuit name: %s", name) - logger.info("******************************") - logger.info(node_circuit.qasm()) - # current method to turn it a DAG quantum circuit. - unrolled_circuit = Unroller(node_circuit, CircuitBackend(basis_gates.split(","))) - circuit_unrolled = unrolled_circuit.execute() + warnings.warn( + "QuantumProgram.load_qasm_file() will be deprecated in upcoming versions (>0.5.0). " + "Using qiskit.load_qasm_file() instead is recommended.", DeprecationWarning) + circuit_unrolled = qiskit.wrapper.load_qasm_file(qasm_file, name, basis_gates) self.add_circuit(name, circuit_unrolled) return name @@ -449,16 +439,10 @@ def load_qasm_text(self, qasm_string, name=None, str: Adds a quantum circuit with the gates given in the qasm string to the quantum program. """ - node_circuit = Qasm(data=qasm_string).parse() # Node (AST) - if not name: - # Get a random name if none is given - name = str(uuid.uuid4()) - logger.info("circuit name: %s", name) - logger.info("******************************") - logger.info(node_circuit.qasm()) - # current method to turn it a DAG quantum circuit. - unrolled_circuit = Unroller(node_circuit, CircuitBackend(basis_gates.split(","))) - circuit_unrolled = unrolled_circuit.execute() + warnings.warn( + "QuantumProgram.load_qasm_text() will be deprecated in upcoming versions (>0.5.0). " + "Using qiskit.load_qasm_text() instead is recommended.", DeprecationWarning) + circuit_unrolled = qiskit.wrapper.load_qasm_string(qasm_string, name, basis_gates) self.add_circuit(name, circuit_unrolled) return name diff --git a/qiskit/wrapper/__init__.py b/qiskit/wrapper/__init__.py index d7bfe31578f0..714252c669d2 100644 --- a/qiskit/wrapper/__init__.py +++ b/qiskit/wrapper/__init__.py @@ -24,4 +24,5 @@ """ from ._wrapper import (available_backends, local_backends, remote_backends, - get_backend, compile, execute, register) + get_backend, compile, execute, register, + load_qasm_string, load_qasm_file) diff --git a/qiskit/wrapper/_wrapper.py b/qiskit/wrapper/_wrapper.py index add371e71b9e..14d783970fda 100644 --- a/qiskit/wrapper/_wrapper.py +++ b/qiskit/wrapper/_wrapper.py @@ -16,18 +16,22 @@ # ============================================================================= """Helper module for simplified QISKit usage.""" +import os import qiskit._compiler from qiskit import QISKitError from qiskit.backends.ibmq.ibmqprovider import IBMQProvider from qiskit.wrapper.defaultqiskitprovider import DefaultQISKitProvider from qiskit import QuantumJob +from qiskit.qasm import Qasm +from qiskit.unroll import Unroller, CircuitBackend + # Default provider used by the rest of the functions on this module. Please # note that this is a global object. _DEFAULT_PROVIDER = DefaultQISKitProvider() -def register(token, url, +def register(token, url='https://quantumexperience.ng.bluemix.net/api', hub=None, group=None, project=None, proxies=None, verify=True, provider_name='ibmq'): """ @@ -202,3 +206,56 @@ def execute(circuits, backend, q_job = QuantumJob(qobj, backend=backend, preformatted=True, resources={ 'max_credits': qobj['config']['max_credits']}) return backend.run(q_job) + + +# Functions for importing qasm + + +def load_qasm_string(qasm_string, name=None, + basis_gates="id,u0,u1,u2,u3,x,y,z,h,s,sdg,t,tdg,rx,ry,rz," + "cx,cy,cz,ch,crz,cu1,cu3,swap,ccx,cswap"): + """Construct a quantum circuit from a qasm representation (string). + + Args: + qasm_string (str): a string of qasm, or a filename containing qasm. + basis_gates (str): basis gates for the quantum circuit. + name (str or None): the name of the quantum circuit after loading qasm + text into it. If no name given, assign automatically. + Returns: + QuantumCircuit: circuit constructed from qasm. + Raises: + QISKitError: if the string is not valid QASM + """ + node_circuit = Qasm(data=qasm_string).parse() + unrolled_circuit = Unroller(node_circuit, CircuitBackend(basis_gates.split(","))) + circuit_unrolled = unrolled_circuit.execute() + if name: + circuit_unrolled.name = name + return circuit_unrolled + + +def load_qasm_file(qasm_file, name=None, + basis_gates="id,u0,u1,u2,u3,x,y,z,h,s,sdg,t,tdg,rx,ry,rz," + "cx,cy,cz,ch,crz,cu1,cu3,swap,ccx,cswap"): + """Construct a quantum circuit from a qasm representation (file). + + Args: + qasm_file (str): a string for the filename including its location. + name (str or None): the name of the quantum circuit after + loading qasm text into it. If no name is give the name is of + the text file. + basis_gates (str): basis gates for the quantum circuit. + Returns: + QuantumCircuit: circuit constructed from qasm. + Raises: + QISKitError: if the file cannot be read. + """ + if not os.path.exists(qasm_file): + raise QISKitError('qasm file "{0}" not found'.format(qasm_file)) + if not name: + name = os.path.splitext(os.path.basename(qasm_file))[0] + + with open(qasm_file) as file: + qasm_data = file.read() + + return load_qasm_string(qasm_data, name=name, basis_gates=basis_gates) diff --git a/test/python/test_load_qasm.py b/test/python/test_load_qasm.py new file mode 100644 index 000000000000..ef126c46d456 --- /dev/null +++ b/test/python/test_load_qasm.py @@ -0,0 +1,144 @@ +# -*- 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. +# ============================================================================= + +from qiskit import QISKitError +from qiskit.wrapper import load_qasm_file, load_qasm_string +from .common import QiskitTestCase, Path + + +class LoadQasmTest(QiskitTestCase): + """Test load_qasm_* set of methods.""" + + def setUp(self): + self.QASM_FILE_NAME = 'entangled_registers.qasm' + self.QASM_FILE_PATH = self._get_resource_path( + 'qasm/' + self.QASM_FILE_NAME, Path.EXAMPLES) + + def test_load_qasm_file(self): + """Test load_qasm_file and get_circuit. + + If all is correct we should get the qasm file loaded in QASM_FILE_PATH + + Previously: + Libraries: + from qiskit.wrapper import load_qasm_file + """ + q_circuit = load_qasm_file(self.QASM_FILE_PATH) + qasm_string = q_circuit.qasm() + self.log.info(qasm_string) + expected_qasm_string = """\ +OPENQASM 2.0; +include "qelib1.inc"; +qreg a[4]; +qreg b[4]; +creg c[4]; +creg d[4]; +h a[0]; +h a[1]; +h a[2]; +h a[3]; +cx a[0],b[0]; +cx a[1],b[1]; +cx a[2],b[2]; +cx a[3],b[3]; +barrier a[0],a[1],a[2],a[3]; +barrier b[0],b[1],b[2],b[3]; +measure a[0] -> c[0]; +measure a[1] -> c[1]; +measure a[2] -> c[2]; +measure a[3] -> c[3]; +measure b[0] -> d[0]; +measure b[1] -> d[1]; +measure b[2] -> d[2]; +measure b[3] -> d[3]; +""" + self.assertEqual(qasm_string, expected_qasm_string) + + def test_fail_load_qasm_file(self): + """Test fail_load_qasm_file. + + If all is correct we should get a QISKitError + + Previously: + Libraries: + from qiskit import QISKitError + from qiskit.wrapper import load_qasm_file + """ + self.assertRaises(QISKitError, + load_qasm_file, "", name=None) + + def test_fail_load_qasm_string(self): + """Test fail_load_qasm_string. + + If all is correct we should get a QISKitError + + Previously: + Libraries: + from qiskit import QISKitError + from qiskit.wrapper import load_qasm_string + """ + self.assertRaises(QISKitError, + load_qasm_string, "", name=None) + + def test_load_qasm_text(self): + """Test load_qasm_text and get_circuit. + + If all is correct we should get the qasm file loaded from the string + + Previously: + Libraries: + from qiskit import QuantumProgram + """ + qasm_string = "// A simple 8 qubit example\nOPENQASM 2.0;\n" + qasm_string += "include \"qelib1.inc\";\nqreg a[4];\n" + qasm_string += "qreg b[4];\ncreg c[4];\ncreg d[4];\nh a;\ncx a, b;\n" + qasm_string += "barrier a;\nbarrier b;\nmeasure a[0]->c[0];\n" + qasm_string += "measure a[1]->c[1];\nmeasure a[2]->c[2];\n" + qasm_string += "measure a[3]->c[3];\nmeasure b[0]->d[0];\n" + qasm_string += "measure b[1]->d[1];\nmeasure b[2]->d[2];\n" + qasm_string += "measure b[3]->d[3];" + q_circuit = load_qasm_string(qasm_string) + qasm_data_string = q_circuit.qasm() + self.log.info(qasm_data_string) + expected_qasm_data_string = """\ +OPENQASM 2.0; +include "qelib1.inc"; +qreg a[4]; +qreg b[4]; +creg c[4]; +creg d[4]; +h a[0]; +h a[1]; +h a[2]; +h a[3]; +cx a[0],b[0]; +cx a[1],b[1]; +cx a[2],b[2]; +cx a[3],b[3]; +barrier a[0],a[1],a[2],a[3]; +barrier b[0],b[1],b[2],b[3]; +measure a[0] -> c[0]; +measure a[1] -> c[1]; +measure a[2] -> c[2]; +measure a[3] -> c[3]; +measure b[0] -> d[0]; +measure b[1] -> d[1]; +measure b[2] -> d[2]; +measure b[3] -> d[3]; +""" + self.assertEqual(qasm_data_string, expected_qasm_data_string) From 0de2825235b87756911a7e7e8141a72098f0fe50 Mon Sep 17 00:00:00 2001 From: Juan Gomez Date: Mon, 28 May 2018 19:12:35 +0200 Subject: [PATCH 20/22] Remove -march=native from compiler flags, as the code it was (#516) generating was not 100% compatible with all CPUs of the same architecture. The loss of performance is negligible. --- cmake/defaults.cmake | 13 ++++++++++++- src/qasm-simulator-cpp/CMakeLists.txt | 1 - 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/cmake/defaults.cmake b/cmake/defaults.cmake index 64c5f0c4cafa..3095545564a2 100644 --- a/cmake/defaults.cmake +++ b/cmake/defaults.cmake @@ -3,12 +3,23 @@ # out$ cmake -DSTATIC_LINKING=True .. # +# Set the build type: Release or Debug set(CMAKE_BUILD_TYPE "Release") + +# Set the type of linking we want to make for native code. Static builds are +# great for distributing. Apple doesn't allow full static linking, so only user +# libraries will be included in the final binary. set(STATIC_LINKING False CACHE BOOL "Static linking of executables") + +# Enable or disable CMake targets that depends on native code. set(ENABLE_TARGETS_NON_PYTHON True CACHE BOOL "Enable targets for non Python code") + +# Enable or disable CMake targets for Q&A: tests/linter/style set(ENABLE_TARGETS_QA True CACHE BOOL "Enable targets for QA targets") + +# Detect platform bit size if(CMAKE_SIZEOF_VOID_P EQUAL 8) set(ARCH64 True CACHE BOOL "We are on a 64 bits platform") elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) set(ARCH32 True CACHE BOOL "We are on a 32 bits platform") -endif() \ No newline at end of file +endif() diff --git a/src/qasm-simulator-cpp/CMakeLists.txt b/src/qasm-simulator-cpp/CMakeLists.txt index 39cfa606cbdb..529b65e07d92 100755 --- a/src/qasm-simulator-cpp/CMakeLists.txt +++ b/src/qasm-simulator-cpp/CMakeLists.txt @@ -60,7 +60,6 @@ endif() if(NOT MSVC) # Compiler flags enable_cxx_compiler_flag_if_supported("-O3") - enable_cxx_compiler_flag_if_supported("-march=native") # Warnings and Errors enable_cxx_compiler_flag_if_supported("-pedantic") enable_cxx_compiler_flag_if_supported("-Wall") From 5c1c68a5aa3dcccdf5c10f9eb307383ebb40826b Mon Sep 17 00:00:00 2001 From: Paul Nation Date: Tue, 29 May 2018 03:34:22 -0400 Subject: [PATCH 21/22] Bump upper limits on requirements packages to next minor release number (#509) * Increase upper bounds on packages --- requirements.txt | 6 +++--- setup.py.in | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/requirements.txt b/requirements.txt index 4640894ea91e..8883ee46b901 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ matplotlib>=2.1,<2.2 networkx>=2.0,<2.1 numpy>=1.13,<1.15 ply==3.10 -scipy>=0.19,<1.1 -sympy>=1.0 -pillow>=4.2.1 +scipy>=0.19,<1.2 +sympy>=1.0,<1.2 +pillow>=4.2.1,<5.2 cmake>=3.11,<3.12 diff --git a/setup.py.in b/setup.py.in index 0cfc08732a53..2b37dc602977 100755 --- a/setup.py.in +++ b/setup.py.in @@ -27,14 +27,14 @@ from setuptools.dist import Distribution requirements = [ - "IBMQuantumExperience>=1.9.0", + "IBMQuantumExperience>=1.9.1", "matplotlib>=2.1,<2.2", "networkx>=2.0,<2.1", "numpy>=1.13,<1.15", "ply==3.10", - "scipy>=0.19,<1.1", - "sympy>=1.0", - "pillow>=4.2.1" + "scipy>=0.19,<1.2", + "sympy>=1.0,<1.2", + "pillow>=4.2.1,<5.2" ] From f9803b55fe9f70daf0f2625a427b1abac1ee6b6b Mon Sep 17 00:00:00 2001 From: Juan Gomez Date: Tue, 29 May 2018 09:36:44 +0200 Subject: [PATCH 22/22] pip release: 0.5.3 --- CMakeLists.txt | 2 +- qiskit/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index be85e0709c42..c257e02d24b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required (VERSION 3.5 FATAL_ERROR) -project (QISKit VERSION 0.5.2 LANGUAGES CXX) +project (QISKit VERSION 0.5.3 LANGUAGES CXX) # Verbose!! set(CMAKE_VERBOSE_MAKEFILE True) diff --git a/qiskit/__init__.py b/qiskit/__init__.py index 348fd5ba88b7..7cb33c7754db 100644 --- a/qiskit/__init__.py +++ b/qiskit/__init__.py @@ -47,4 +47,4 @@ # Import the wrapper, to make it available when doing "import qiskit". from . import wrapper -__version__ = '0.5.2' +__version__ = '0.5.3'