Release Notes#

0.3.1#

New Features#

  • Add support and build wheels for Python 3.12.

  • Build C++ extensions with Cython 3.

0.3.0#

New Features#

  • Adds support for compiling circuits into the Quantum Intermediate Representation (QIR) language using PyQIR API and qirlib LLVM wrapper.

    circuit = Circuit(2)
    
    with circuit.context as reg:
        ops.X(reg.q[0])
        ops.Y(reg.q[1])
    
    qir_string = circuit.to_qir()
    

    Circuits can also be compiled directly into bitcode.

    qir_string = circuit.to_qir(bitcode=True)
    
  • Adds a Quantum Intermediate Representation (QIR) loader which consumes a QIR script and returns a corresponding circuit containing the same instruction.

    ; ModuleID = 'Citrus'
    source_filename = "Citrus"
    
    %Qubit = type opaque
    
    define void @main() {
      entry:
      call void @__quantum__rt__initialize(i8* null)
      call void @__quantum__qis__x__body(%Qubit* null)
      call void @__quantum__qis__y__body(%Qubit* inttoptr (i64 1 to %Qubit*))
      ret void
    }
    
    declare void @__quantum__rt__initialize(i8*)
    declare void @__quantum__qis__x__body(%Qubit*)
    declare void @__quantum__qis__y__body(%Qubit*)
    

    The above QIR script can be loaded into a dwave-gate circuit using the dwave.gate.qir.loader.load_qir_string function.

    from dwave.gate.qir.loader import load_qir_string
    
    circuit = load_qir_string(qir_string, circuit=circuit)
    

Upgrade Notes#

  • Upgrade circuit call to accept classical bits in which to store measurement values. If no bits are passed to the circuit call, measurements will not be stored when circuit is simulated.

    circuit = Circuit(2, 2)
    
    with circuit.context as (q, c):
        ops.Hadamard(q[0])
        ops.Hadamard(q[1])
        ops.Measurement(q) | c
    
    circuit_2 = Circuit(2, 2)
    
    with circuit_2.context as (q, c):
        circuit(q, c)  # pass bits to 'circuit'
    

Deprecation Notes#

  • Support for Python 3.7 deprecated.

Bug Fixes#

  • Fix return type from Operation.__call__ and subclasses.

  • Fixes loading QIR scripts with a return mid-function.

  • Fix circular import issue when importing the simulator prior operations.

0.2.1#

New Features#

  • Measurement samples can be returned as bitstrings instead of integers in nested lists.

  • A density matrix representation of the state can be accessed via the Circuit.density_matrix property, for both pure and mixed states (with the former being lazily calculated from the state vector).

Upgrade Notes#

  • Adds support for multi-qubit sampling in measurements. Measurement.sample() and Measurement.expval() are updated to accept a sequence of qubit indices to sample, sampling all measured qubits if none are given.

    circuit = Circuit(2, 2)
    
    with circuit.context as (q, c):
        ops.X(q[0])
        m = ops.Measurement(q) | c
    
    simulate(circuit)
    
    m.sample(num_samples=3, as_bitstring=True)
    # ['10', '10', '10']
    
  • The state is now stored in the Circuit object (same as the bits/measurement results) instead of being returned by the simulate() function. It can now be accessed via the Circuit.state property.

0.2.0#

Prelude#

We began using Reno as a changelog tool after the first release, version 0.1.0. Features that were part of that release are not included in the changelog.

New Features#

  • Adds the get_qubit method to the Circuit class allowing for the retrieval of qubits in the circuit by label.

    circuit = Circuit()
    circuit.add_qubit(Qubit("my_qubit"))
    
    qubit = circuit.get_qubit("my_qubit")
    
  • Add support for mid-circuit measurements.

  • Add support for operations conditioned on measurements.

  • Add support for measurement sampling and expectation value calculations.

  • Circuit context returns the classical register together with QuantumRegister. The two registers are contained within a tuple and are returned as with circuit.context as (q, c), instead of with circuit.context as q.

    circuit = Circuit(2, 2)
    
    with circuit.context as (q, c):
        ops.X(q[0])
    
  • Add a Windows executable makefile (make.bat)

  • Add make docs and make clean-docs commands to the makefile for building and cleaning/removing the documentation locally.

Upgrade Notes#

  • Update context to return a NamedTuple instead of a regular tuple, allowing for the registers to be returned as previously, directly unpacked into q and c, or as a named Registers tuple and retrieved via Registers.q and Registers.c respectively.

  • Update parametric context to return a NamedTuple instead of a regular tuple similar to the non-parametric context upgrade, with the parameter register accessed via Registers.p.

    circuit = ParametricCircuit(2, 2)
    
    with circuit.context as reg:
        ops.RX(reg.p[0], reg.q[0])
    
  • Check types when adding qubits/bits to a circuit and raise a TypeError if an incorrect type is passed to the method.

  • Rename label to name for operations.

Bug Fixes#

  • Fixes an issue where an error is being raised when subsequent measurements are made on the same qubit. Instead, any subsequent measurement will replace the former one at simulation runtime.

  • Fix inconsistent spacing in primitive object representations.

  • Fix sequential qubit/bit labelling when adding new registers.

  • Update operation representations to use repr() for hashables.

  • Adds pip installation step to make install command.

  • Expand installation section in the README to include installation on Windows (using make.bat) and add details to installation steps.