Coder Social home page Coder Social logo

cqcl / tket Goto Github PK

View Code? Open in Web Editor NEW
244.0 17.0 48.0 408.61 MB

Source code for the TKET quantum compiler, Python bindings and utilities

Home Page: https://tket.quantinuum.com/

License: Apache License 2.0

Shell 0.01% CMake 0.77% C++ 69.93% Python 28.63% Makefile 0.01% HTML 0.02% OpenQASM 0.47% JavaScript 0.01% C 0.04% Nix 0.11% Rust 0.02%
quantum-computing compiler

tket's Introduction

tket

Slack Stack Exchange PyPI version

Introduction

TKET (pronounced "ticket") is a high-performance quantum compiler that can optimise circuits for a wide range of quantum computing architectures.

This repository contains the full source code for TKET and its python bindings.

The standard way of using TKET is via its pytket python API.

If you just want to use TKET via Python, the easiest way is to install pytket with pip:

pip install pytket

As well as being an interface to the TKET compiler, pytket also provides an extensive API for other quantum computing tasks. These include constructing quantum circuits and handling the execution of experiments on devices and simulators.

Documentation

The tket (C++) API documentation (generated with doxygen, and still rather patchy) is available here.

The pytket (Python) API documentation is available here.

For getting started using pytket, check out the user manual and notebook examples.

The source content for the manual and notebook examples can be found in the pytket-docs repository.

Extensions

In addition to the core pytket package there are pytket extension modules which allow pytket to interface with quantum devices and simulators. Some extensions also provide interoperability with other software libraries such as qiskit, cirq and pennylane.

For a list of available pytket extensions see the extensions index page.

These extensions are installed as separate python packages and the source code for each extension lives in its own github repository.

How to build TKET and pytket

If you would like to build TKET yourself and help to improve it, read on!

The codebase is split into two main projects:

  • tket: the core functionality of tket, optimised for execution speed and implemented in C++.
  • pytket: the Python interface of tket. This consists of binder modules to tket (written in C++ and making use of pybind11 to link to the tket shared library) and pure Python code that defines abstract interfaces used by the extension modules such as the Backend and BackendResult classes, as well as various other utilities.

Prerequisites

Build tools

The following compiler toolchains are used to build tket on the CI and are therefore known to work:

  • Linux: gcc-13
  • MacOS: apple-clang 15
  • Windows: MSVC 19

It is recommended that you use these versions to build locally, as code may depend on the features they support. The compiler version can be controlled by setting CC and CXX in your environment (e.g. CC=gcc-11 and CXX=g++-11), or on Debian-based Linux systems using update-alternatives.

You should also have Python (3.10, 3.11 or 3.12) and pip installed. We use cmake and the package manager conan to build tket and pytket. The latter can be installed with pip:

pip install conan

You will need at least cmake version 3.26, and conan version 2.

Set up conan profile

Generate a profile that matches your current machine, and add the required remote where some dependencies are stored:

conan profile detect
conan remote add tket-libs https://quantinuumsw.jfrog.io/artifactory/api/conan/tket1-libs --index 0

Optional: use ninja and ccache

It is recommended that you also install ninja and ccache to speed up the build process. For example with apt on Debian/Ubuntu:

apt install ninja-build ccache

Homebrew on MacOS/Linux:

brew install ninja ccache

Chocolatey on Windows:

choco install ninja ccache

On MacOS/Linux:

  • If installed, ccache is used automatically
  • ninja must either be set as the default Cmake generator using the following command:
    echo "tools.cmake.cmaketoolchain:generator = Ninja" >> $(conan config home)/global.conf
    or be specified on a command-by-command basis by providing the argument -c tools.cmake.cmaketoolchain:generator=Ninja to conan

On Windows:

  • Set ninja as generator as described above (less reliable than the default Visual Studio generator)
  • ccache will be used automatically only when using Ninja or Makefile as the Cmake generator. It can also be used with Visual Studio generators by setting the environment variable TKET_VSGEN_CCACHE_EXE to the path of the ccache executable. Note: this must be the path to the actual binary, not a symlink or shim (as used by Chocolatey). If using Chocolatey to install ccache, you can find the path to the binary using ccache --shimgen-help

Building and testing the utility libraries

See the README in the libs directory for instructions on building and testing the utility libraries used by tket (for logging, random-number generation and so on). This is not necessary if you just want to build tket or pytket since the recipes or binaries will be automatically downloaded from the above conan remote.

Building and testing the tket library

See the README in the tket directory for instructions on building and testing tket as a standalone C++ library.

Building and testing pytket

See the README in the pytket directory for instructions on building and testing pytket.

Nix Support

Tket and pytket are available as a Nix flake, with support for Linux and Apple Silicon systems. See the README in the nix-support directory for instructions on building and testing tket and pytket through Nix, and on how to use it within a Nix project.

To launch into a tket environment, you can use

nix develop github:CQCL/tket

We use Cachix to cache pre-built artifacts, which provides a faster install time for nix users. To make use of this cache, enable our cachix substituter with cachix use tket, or enter a tket nix environment from a trusted user and confirm the use of the tket.cachix.org substituter.

tket's People

Contributors

1tnguyen avatar aborgna-q avatar aidancq avatar alexcowtan avatar andrew-tranter avatar calmaccq avatar cqc-alec avatar cqc-melf avatar daniel-mills-cqc avatar dependabot[bot] avatar dlyongemallo avatar dna386 avatar domnomnom avatar drzenharper avatar ferbetanzo avatar jake-arkinstall avatar johnchildren avatar lmondada avatar monitsharma avatar pabloandrescq avatar qartik avatar quantinuum-richard-morrison avatar roland-djee avatar sjdilkes avatar srulre avatar ss2165 avatar trvto avatar vtomole avatar willsimmons1465 avatar yao-cqc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tket's Issues

Add `allow_swaps` option to `FullPeepholeOptimise`.

There isn't an option to disallow wireswaps when applying FullPeepholeOptimise. One can construct an equivalent pass that doesn't allow wireswaps:

FullPeepholeOptimiseNoSwaps = SequencePass(
    [
        SynthesiseTket(),
        KAKDecomposition(),
        CliffordSimp(allow_swaps=False),
        SynthesiseTket(),
        ThreeQubitSquash(allow_swaps=False),
        CliffordSimp(allow_swaps=False),
        SynthesiseTket(),
    ]
)

But it would be better to add an allow_swaps option to the high-level pass.

Use rule of zero wherever possible. Add move semantics otherwise.

We currently ignore the existence of move semantics in bubble. That might be having an impact on performance (probably hard to quantify though).

With modern C++, most classes should be able to get by without managing any memory themselves. These classes should follow the rule of zero. If specific memory manipulations are necessary, there should be dedicated classes for that purpose and they should follow the rule of five.

Note: I don't know what the status is for the BGL. Copying graph can invalidate references to vertices etc., so one should think of an elegant solution to this problem if we want to follow the rule of 0.

TK1 dagger is incorrect

It is missing a minus sign on the middle parameter:

    case OpType::tk1:
      // tk1(a,b,c).dagger() == tk1(-c,-b,-a)
      {
        return get_op_ptr(OpType::tk1, {-params_[2], params_[1], -params_[0]});
      }

Add access to opgroups from pytket

It has been requested that we add the following two methods to Circuit:

  • opgroups(), returning a set of str (all named opgroups);
  • ops_in_group(opgroup: str), returning a set of Op (all ops in a given opgroup).

Add `delay_measures` option to `DefaultMappingPass`, defaulting to true.

Currently DefaultMappingPass can introduce mid-circuit measurements, but only ones that can be commuted to the end of the circuit using DelayMeasures. In particular it can introduce SWAP gates following measures that do not have unitary semantics. Similarly to CXMappingPass, we should add an option to apply DelayMeasures as part of the pass.

An example showing the issue:

from pytket.circuit import Circuit
from pytket.passes import DefaultMappingPass
from pytket.routing import Architecture

c = Circuit(4)
c.CX(0, 1)
c.CX(1, 2)
c.CX(2, 3)
c.CX(3, 0)
c.measure_all()

arc = Architecture([(0, 2), (1, 2), (2, 3)])

DefaultMappingPass(arc).apply(c)

print(c.get_commands())

Output:

[CX node[0], node[2];, CX node[2], node[1];, Measure node[2] --> c[1];, SWAP node[2], node[3];, CX node[1], node[2];, Measure node[1] --> c[2];, CX node[2], node[0];, Measure node[0] --> c[0];, Measure node[2] --> c[3];]

Abolish `new`.

There are a few places in the code where we still use new to construct a unique_ptr; we should replace these with make_unique.

Occasional hypothesis test failures on CI due to timeouts

Two recent examples:

---------------------------------- Hypothesis ----------------------------------
Falsifying example: test_const_predicate(
    condition=BitEq(op=<BitWiseOp.EQ: '=='>, args=[BitOr(op=<BitWiseOp.OR: '|'>, args=[BitXor(op=<BitWiseOp.XOR: '^'>, args=[BitXor(op=<BitWiseOp.XOR: '^'>, args=[BitOr(op=<BitWiseOp.OR: '|'>, args=[BitOr(op=<BitWiseOp.OR: '|'>, args=[BitXor(op=<BitWiseOp.XOR: '^'>, args=[oPvu3lL5eLyCVTc6dwOLYz[85], 0]), 0]), 1]), 1]), 1]), 1]), 1]),
)
Unreliable test timings! On an initial run, this test took 1184.59ms, which exceeded the deadline of 200.00ms, but on a subsequent run it took 5.20 ms, which did not. If you expect this sort of variability in your test timings, consider turning deadlines off for this test by setting deadline=None.
--------------------------------- Hypothesis ----------------------------------
Falsifying example: test_status_serialization(\n    status=<StatusEnum.COMPLETED: 'Circuit has completed. Results are ready.'>,\n    message="\\x07\xef\ubbc8\\U00084723j\xdd'",\n)\nUnreliable test timings! On an initial run, this test took 809.19ms, which exceeded the deadline of 200.00ms, but on a subsequent run it took 0.05 ms, which did not. If you expect this sort of variability in your test timings, consider turning deadlines off for this test by setting deadline=None.

Enhance `CliffordSimp` to handle CX inversions

CliffordSimp fails to simplify the circuit Circuit(2).H(0).H(1).CX(0,1).H(0).H(1) (equivalent to Circuit(2).CX(1,0)). We should enhance the pass so that it spots this kind of pattern.

Avoid linker warnings from `fmt` on MacOS

MacOS builds of pytket include a lot of warnings like:

ld: warning: direct access in function 'fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender, int, 0>(fmt::v8::appender, int)' from file 'CMakeFiles/circuit.dir/binders/circuit/Circuit/main.cpp.o' to global weak symbol 'fmt::v8::detail::basic_data<void>::digits' from file '/Users/runner/.conan/data/fmt/8.0.1/_/_/package/e49065ecb5f0d44c4e32f570e965f6a1bd08dd0e/lib/libfmt.a(format.cc.o)' means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.

Not sure if these matter but it would be good to remove them.

The fmt library is a depenency of spdlog. It has a header_only option which could be worth investigating.

Update to apple-clang 13.

This is now the default for macos-11 builds on github. We can't update yet because of some missing conan packages.

Enable smart placement for architecture-aware synthesis

Currently, the only architecture-aware synthesis method is for phase polynomials (and therefore CNOT circuits).
Within the synthesis code, the placement of logical qubits on the physical architecture is implicitly chosen around

or so.

The only placement which is chosen in a "smart" way is in the CNotSynthType::HamPath case (and even then, it just uses the first Hamiltonian path it can find). We should add a placement method for at least the CNotSynthType::Rec as well. The CNotSynthType::SWAP case is low priority, as it is just a default naive method for a baseline comparison.

We already use a global_cost to choose phase polynomial decompositions, so we could use this to choose placements as well. The complexity of this in the general case will be awful, as the number of possible placements will explode combinatorially and it requires the construction of a Steiner tree for each placement. We could implement a timeout, such as with the Hamiltonian path method and the subgraph isomorphism for traditional routing, or find an alternative approach.

This is related to #23, as we may in general want to make use of a larger portion of the architecture than there are qubits in the logical circuit.

More intelligent handling of SWAP gates in synthesis passes

Routing introduces SWAP gates; when followed by synthesis passes these are often decomposed to sequences of CX gates. The CX sequence may depend on the order of qubits in the SWAP, and this can have an effect on cancellation.

For example:

from pytket import Circuit, OpType
from pytket.passes import SynthesiseTket


def synthesise(c):
    SynthesiseTket().apply(c)
    print(c.get_commands())


circ0 = Circuit(2).CX(0, 1).SWAP(0, 1)
circ1 = Circuit(2).CX(0, 1).SWAP(1, 0)

synthesise(circ0)
synthesise(circ1)

outputs:

[CX q[1], q[0];, CX q[0], q[1];]
[CX q[0], q[1];, CX q[1], q[0];, CX q[0], q[1];, CX q[1], q[0];]

In the case of circ1 the synthesized circuit has two more CX gates.

This is the underlying cause of CQCL/pytket-docs#107 .

Segmentation fault in `AASRouting` pass

The following code segfaults:

from pytket import Circuit
from pytket.routing import Architecture
from pytket.passes import AASRouting

arch = Architecture([[0,1], [1,0], [1,2], [2,1]])
circ = Circuit(2).CZ(0,1)
AASRouting(arch).apply(circ)

If the circuit has 3 qubits, or the architecture has 2 nodes, then the code runs fine: the problem seems to occur when routing a circuit to a larger architecture.

No wireswap handling in the creation of a phase poly box

Wireswaps are not handled in the creation of a phase poly box, this should be changed.

Circuit circ(2);
circ.add_op<unsigned>(OpType::SWAP, {0, 1});
circ.replace_SWAPs();
std::cout << "has wireswaps: " << circ.has_implicit_wireswaps()
          << std::endl;
PhasePolyBox ppbox(circ);
std::shared_ptr<Circuit> circptr = ppbox.to_circuit();
Circuit circ2 = *circptr;
for (auto c : circ2) {
  c.print();
}
std::cout << "has wireswaps: " << circ2.has_implicit_wireswaps()
          << std::endl;
REQUIRE(test_unitary_comparison(circ, circ2));

Will fail with:

Begin testcase: single SWAP circuit in PhasePolyBox
has wireswaps: 1
has wireswaps: 0

test_tket is a Catch v2.13.7 host application.
Run with -? for options

FAILED:
  REQUIRE( test_unitary_comparison(circ, circ2) )
with expansion:
  false

Numerical instability in `tk1_angles_from_unitary`

It is possible to create a Unitary1qBox whose circuit decomposition contains a nan parameter:

from pytket.circuit import Unitary1qBox
import numpy as np

u = np.array([[-1.0000000000000000e+00+0.0000000000000000e+00j,
               -4.7624091282918654e-10+2.0295010872500105e-16j],
              [ 4.5447577055178555e-10-1.4232772405184710e-10j,
               -9.5429791447115209e-01+2.9885697320961047e-01j]])

ubox = Unitary1qBox(u)
print(ubox.get_circuit().get_commands())
[TK1(3.40339, nan, 0.5) q[0];]

QASM conversion ignores parameters in conditional gates.

I think I must have introduced this bug with #8.

from pytket.qasm import circuit_to_qasm_str
from pytket.circuit import Circuit, OpType

c = Circuit(1, 1)
c.add_gate(OpType.PhasedX, [1, 0], [0], condition_bits=[0])

print(circuit_to_qasm_str(c, header="hqslib1"))

Output:

OPENQASM 2.0;
include "hqslib1.inc";

qreg q[1];
creg c[1];
if(c[0]==1) U1q q[0];

The U1q gate is missing its parameters.

ConnectivityPredicate fails after FullPeepholeOptimise and AASRouting

The problem can be generated with:

from pytket.predicates import ConnectivityPredicate
from pytket.passes import (
    FullPeepholeOptimise,
    AASRouting,
    SequencePass,
)
from pytket.routing import Architecture
from pytket import Circuit
import json

coupling_map = [[0, 1], [0, 14], [1, 0], [1, 2], [1, 13], [2, 1], [2, 3], [2, 12], [3, 2], [3, 4], [3, 11], [4, 3], [4, 5], [4, 10], [5, 4], [5, 6], [5, 9], [6, 5], [6, 8], [7, 8], [8, 6], [8, 7], [8, 9], [9, 5], [9, 8], [9, 10], [10, 4], [10, 9], [10, 11], [11, 3], [11, 10], [11, 12], [12, 2], [12, 11], [12, 13], [13, 1], [13, 12], [13, 14], [14, 0], [14, 13]]
device = Architecture(coupling_map)
connectivity_pred = ConnectivityPredicate(device)

with open('aas_connectivity_pred.json', 'r') as fp:
    orig_circ = Circuit().from_dict(json.load(fp))
    
new_circ_pytket_aas = orig_circ.copy()

FullPeepholeOptimise(allow_swaps=True).apply(new_circ_pytket_aas)
AASRouting(device).apply(new_circ_pytket_aas) 

assert connectivity_pred.verify(new_circ_pytket_aas)```

Make coverage a required check on PRs

Unfortunately, making it a merge requirement means that when it doesn't run (because the bubble directory is unchanged) we can't merge the PR. It seems that the only workaround is to have it always run, but just return status 0 if there are no changes in bubble.

Race condition between workflows that update `gh-pages` branch

Several CI workflows update the gh-pages branch to build coverage, bubble or pytket documentation. If these are interleaved they may fail because git can't push to the branch (or update from develop).

In such cases they can be rerun at a later time, but we should find a better way to avoid this race condition.

Document how to install pytket on M1 Mac

On an M1 Mac it is necessary to:

  1. install brew;
  2. brew install openblas;
  3. pip install -U pip wheel;
  4. OPENBLAS="$(brew --prefix openblas)" pip install scipy;
  5. pip install pytket.

Document this in the relevant places.

Dictionary returned by `BackendInfo.to_dict()` is not JSON-serializable

The documentation says that it is. But:

from pytket.extensions.qiskit import IBMQBackend, IBMQEmulatorBackend
import json

device_backend = IBMQEmulatorBackend("ibmq_santiago", hub="ibm-q", group="open", project="main")
backend_info_json = device_backend.backend_info.to_dict()
json.dumps(backend_info_json)

produces

TypeError: keys must be str, int, float, bool or None, not pytket._tket.circuit.Node

Support `rxx` gate for `pytket_qasm`.

Before working on adding this, I need confirmation from the maintainers that this is what would like.

Qiskit has a native rxx gate but Pytket's QASM parer can't parse it because rxx hasn't been added to this list . This issue is to track whether or not we should add it.

How to reproduce

from pytket.qasm import circuit_from_qasm, circuit_to_qasm_str
import tempfile, os

fd, path = tempfile.mkstemp(".qasm")
os.write(fd, """OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
creg c[2];
rxx(pi/2) q[0],q[1];
measure q -> c;
""".encode())
os.close(fd)
circ = circuit_from_qasm(path)
os.remove(path)

Throws

TypeError: Cannot parse gate of type: rxx

but it works in Qiskit

import qiskit

circ = qiskit.QuantumCircuit.from_qasm_str("""OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
creg c[2];
rxx(pi / 2) q[0],q[1];
measure q -> c;
""")

Occasional build failures on Windows CI due to heap exhaustion

I thought setting CMAKE_BUILD_PARALLEL_LEVEL=2 in the environment when building on the CI had fixed this issue, but it seems to still occur sometimes: https://github.com/CQCL/tket/runs/4867491927

C:\Users\runneradmin\.conan\data\nlohmann_json\3.10.4\_\_\package\5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9\include\nlohmann/json.hpp(930): fatal error C1060: compiler is out of heap space (compiling source file C:\Users\runneradmin\.conan\data\tket\1.0.1\_\_\build\5c7a2862abf41a4b4e1c2c6362efbc737e8bbe8a\Characterisation\FrameRandomisation.cpp) [C:\Users\runneradmin\.conan\data\tket\1.0.1\_\_\build\5c7a2862abf41a4b4e1c2c6362efbc737e8bbe8a\Characterisation\tket-Characterisation.vcxproj]
C:\.conan\8f95b3\1\include\boost/multiprecision/cpp_int.hpp(1293,1): fatal error C1060: compiler is out of heap space (compiling source file C:\Users\runneradmin\.conan\data\tket\1.0.1\_\_\build\5c7a2862abf41a4b4e1c2c6362efbc737e8bbe8a\Diagonalisation\Diagonalisation.cpp) [C:\Users\runneradmin\.conan\data\tket\1.0.1\_\_\build\5c7a2862abf41a4b4e1c2c6362efbc737e8bbe8a\Diagonalisation\tket-Diagonalisation.vcxproj]
C:\Users\runneradmin\.conan\data\nlohmann_json\3.10.4\_\_\package\5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9\include\nlohmann/detail/input/json_sax.hpp(591,1): fatal error C1060: compiler is out of heap space (compiling source file C:\Users\runneradmin\.conan\data\tket\1.0.1\_\_\build\5c7a2862abf41a4b4e1c2c6362efbc737e8bbe8a\Characterisation\Cycles.cpp) [C:\Users\runneradmin\.conan\data\tket\1.0.1\_\_\build\5c7a2862abf41a4b4e1c2c6362efbc737e8bbe8a\Characterisation\tket-Characterisation.vcxproj]
C:\.conan\8f95b3\1\include\boost/multiprecision/number.hpp(1638,1): fatal error C1060: compiler is out of heap space (compiling source file C:\Users\runneradmin\.conan\data\tket\1.0.1\_\_\build\5c7a2862abf41a4b4e1c2c6362efbc737e8bbe8a\Diagonalisation\DiagUtils.cpp) [C:\Users\runneradmin\.conan\data\tket\1.0.1\_\_\build\5c7a2862abf41a4b4e1c2c6362efbc737e8bbe8a\Diagonalisation\tket-Diagonalisation.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\include\xstddef(200,1): fatal error C1060: compiler is out of heap space (compiling source file C:\Users\runneradmin\.conan\data\tket\1.0.1\_\_\build\5c7a2862abf41a4b4e1c2c6362efbc737e8bbe8a\Program\Program_accessors.cpp) [C:\Users\runneradmin\.conan\data\tket\1.0.1\_\_\build\5c7a2862abf41a4b4e1c2c6362efbc737e8bbe8a\Program\tket-Program.vcxproj]
C:\.conan\8f95b3\1\include\boost/multiprecision/detail/no_et_ops.hpp(433,1): fatal error C1060: compiler is out of heap space (compiling source file C:\Users\runneradmin\.conan\data\tket\1.0.1\_\_\build\5c7a2862abf41a4b4e1c2c6362efbc737e8bbe8a\Program\Program_analysis.cpp) [C:\Users\runneradmin\.conan\data\tket\1.0.1\_\_\build\5c7a2862abf41a4b4e1c2c6362efbc737e8bbe8a\Program\tket-Program.vcxproj]

Is the setting actually being respected? The fact that the error is apparently being emitted while compiling 6 different source files at the same time suggests not...

`SquashHQS` does not squash 2x `PhasedX`

Consider the following circuit

import pytket as tk

c = tk.Circuit(1)
c.add_gate(tk.OpType.PhasedX, [0.5, 0.5], [0])
c.add_gate(tk.OpType.PhasedX, [0.5, 0.5], [0])

The SquashHQS pass should merge these two gates into one, but it does not:

from pytket.passes import SquashHQS

SquashHQS().apply(c)

gives [PhasedX(0.5, 0.5) q[0]; PhasedX(0.5, 0.5) q[0]; ]. Expected: [PhasedX(1, 0.5) q[0]; ].

Phase error in compilation of circuit with X and BRIDGE.

A pi phase error is introduced when applying FullPeepholeOptimise to a circuit consisting of an X and a BRIDGE gate:

from pytket.circuit import Circuit, OpType
from pytket.passes import FullPeepholeOptimise
import numpy as np

c = Circuit(3)
c.add_gate(OpType.X, [1])
c.add_gate(OpType.BRIDGE, [0, 1, 2])

u = c.get_unitary()

FullPeepholeOptimise().apply(c)

u1 = c.get_unitary()

assert np.allclose(u, -u1)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.