Skip to main content

The OpenQL mapper wrapped in a DQCsim operator

Project description

DQCsim OpenQL-mapper operator

PyPi

See also: DQCsim and OpenQL.

This repository contains some glue code to use the OpenQL Mapper as a DQCsim operator.

NOTE: this only works on Linux. Your mileage may vary in general; try building and installing from source if installing through pip doesn't work.

Compile-time mapping (OpenQL) vs runtime mapping (DQCsim + OpenQL)

It is very important to note that DQCsim is a simulator framework, and operators are placed in the purely-quantum gatestream that results from executing any and all classical and mixed quantum-classical instructions, such as loops, if statements, and anything based on measurement results. This results in two major differences between mapping a program with OpenQL and then simulating versus using DQCsim to do it.

  • As a DQCsim operator, the mapper does not have access to the whole program before it is executed; it can only see gates up to the first measurement. This is because any subsequent gate may depend on the measurement result through the classical instructions in the frontend; trying to receive gates past this point may result in a deadlock. This may adversely affect the quality of the mapping.

  • As a DQCsim operator, the mapper maps exactly the actually executed gates. If you for instance have an if-else statement based on a measurement result, the mapper will only see the block that was actually executed based on that measurement. This also means that the virtual-to-physical mappings may change based on the stochastic measurement results from the quantum simulation. Furthermore, if you have a loop, the mapper will be invoked for each loop iteration; this may make it significantly slower, but may in fact improve the mapping result as the mapper doesn't need to insert swaps at the end of the loop body to return to the mapping at the start of the loop. The effect is as if all loops (even those with dynamic conditions) are unrolled. Ultimately, these things should improve the mapping result as more information is available, but may result in longer simulation times.

The computer engineers among us may note that this is exactly the difference between compile-time scheduling (including predication, loop unrolling, etc) and runtime scheduling (Tomasulo, speculation, etc.) in classical computer architecture. Neither is necessarily better than the other, but the results are different. Please keep this in mind when evaluating the mapper results.

Installation

Installation is done through pip, even though this is largely not a Python package. It's just convenient to use it regardlessly. Install as follows:

sudo pip3 install dqcsim-openql-mapper

This allows you to use the openql-mapper operator in DQCsim, and exposes the platform2gates command (more on this in a bit).

Local build/install from source using setup.py

This mimics a complete installation.

git clone https://github.com/QE-Lab/dqcsim-openql-mapper.git --recursive

Note the --recursive there. A working version of OpenQL is included as a subrepo; if you don't check out recursively (or init the subrepo afterwards) compilation will fail.

export DQCSIM_DEBUG=yes # only if you want to do a debug instead of release build.
python3 setup.py build
python3 setup.py bdist_wheel

You'll have to uninstall the previous version (if any) before installation will work:

sudo pip3 uninstall dqcsim-openql-mapper -y

Now you can install:

sudo pip3 install target/python/dist/*

Note that this wheel should NOT be distributed as is; it will probably only work on your system. See release.md for info on complete release builds.

Build from source using CMake

The setup.py script simply defers to CMake for the build. So you can build with any tool based on that for building as well. Your mileage may vary with the install target though, it is not tested.

Running tests

A very rudimentary test is included, which you can run using

python3 setup.py test

The test currently uses the INSTALLED operator. So you always need to reinstall first if you make changes!

Usage

This section assumes you know how DQCsim works. If you don't, start reading here.

To use the openql-mapper operator you need two things:

  • an OpenQL platform description JSON file;
  • a DQCsim <-> OpenQL gatemap JSON file.

The former describes the quantum platform you're compiling for. I'm assuming you already have it, considering you're trying to map an algorithm to some architecture. If you don't, well, look for the relevant OpenQL documentation. Probably its source files.

The latter provides a mapping between DQCsim's gate format (based on non-controlled submatrices and a number of control qubits) and OpenQL's format (based on names). Basically, it tells the operator what for instance a gate with the name "prepz" means.

Initialization arbs

In order to tell the mapper where it should look for the JSON files, you have to either pass it some initialization arbs or set environment variables. Here's the list of commands you can pass:

  • openql_mapper.hardware_config: specifies the hardware config JSON file. The filename must be specified through the first binary string argument.

  • openql_mapper.gatemap: specifies the gatemap JSON file. The filename must be specified through the first binary string argument.

  • openql_mapper.option: sets some OpenQL option (ql::options::set()). The key is specified through the first binary string argument; the value through the second. This command can be specified zero or more times.

If you're working from the command line, using environment variables is easier. The following variables are queried if the above initialization arbs are missing:

  • DQCSIM_OPENQL_HARDWARE_CONFIG: default path for the hardware config file.

  • DQCSIM_OPENQL_GATEMAP: default path for the gatemap config file.

Gatemap JSON files

The format of a gatemap JSON file is quite simple compared to the platform JSON file. It's just a single object mapping from the OpenQL gate name to a DQCsim gate description. Like this:

{
    "<openql-gate-1>": "<dqcsim-gate-1",
    "<openql-gate-2>": "<dqcsim-gate-2",
    "<openql-gate-3>": "<dqcsim-gate-3"
}

The DQCsim gate description can be one of the following:

  • A dictionary with the entries described in the following sections;
  • A string, which is just a simplification of the above. If the string has "C-" prefixes, they are counted and the result is mapped to the "controlled" key; the remainder is interpreted as the type.

Most of the time, the DQCsim gate descriptions are also just simple strings; you should only have to write a more complicated description for exotic gates.

To get started quickly, you can use the platform2gates command-line tool to heuristically convert your platform JSON file into a gatemap file. Usually the tool will guess correctly, but it's worth checking the result even when it manages to generate the complete file. If it doesn't recognize a gate, it just outputs a placeholder for you to fill in.

File format

As stated, the file consists of a mapping from OpenQL gate names to DQCsim gate descriptions. Such a description is one of the following:

  • A dictionary with the entries described in the following sections;
  • A string, which is just a simplification of the above. If the string has "C-" prefixes, they are counted and the result is mapped to the "controlled" key; the remainder is interpreted as the type.

Types

The dictionary described above must contain at least a "type" key, mapping to one of the following built-in strings (case-insensitive):

  • "I" - single-qubit identity gate.
  • "X" - Pauli X.
  • "Y" - Pauli Y.
  • "Z" - Pauli Z.
  • "H" - Hadamard.
  • "S" - 90-degree Z rotation.
  • "S_DAG" - -90-degree Z rotation.
  • "T" - 45-degree Z rotation.
  • "T_DAG" - -45-degree Z rotation.
  • "RX_90" - RX(90).
  • "RX_M90" - RX(-90).
  • "RX_180" - RX(180).
  • "RX" - RX gate with custom angle in radians.
  • "RY_90" - RY(90).
  • "RY_M90" - RY(-90).
  • "RY_180" - RY(180).
  • "RY" - RY gate with custom angle in radians.
  • "RZ_90" - RZ(90).
  • "RZ_M90" - RZ(-90).
  • "RZ_180" - RZ(180).
  • "RZ" - RZ gate with custom angle in radians.
  • "PHASE" - Z rotation with custom angle in radians, affecting the bottom-right matrix entry only. "matrix" or "submatrix" key.
  • "SWAP" - swap gate.
  • "SQSWAP" - square-root-of-swap gate.
  • "unitary" - custom unitary gate. Refer to the section on custom unitaries for more info.
  • "measure" - measurement gate. Refer to the section on measurements for more info.
  • "prep" - state preparation gate. Refer to the section on prep gates for more info.

Custom unitary gates

The "unitary" type allows you to specify the unitary matrix directly, using the "matrix" key. Matrices are specified as a list of lists, where each inner list contains two float entries representing the real and imaginary value of the matrix entry, and the outer list represents the matrix entries in row-major form. Integers are coerced to floats, so you can omit the decimal separator for -1, 0, and 1. The size of the matrix (plus the number of control qubits, if any - see next section) implies the number of qubits affected by the gate. To prevent having to write out irrationals like 1/sqrt(2), the matrices will automatically be normalized. After that, a unitary check is done to detect most typos.

For instance, RX(90) could be written like this:

{
    "type": "unitary",
    "matrix": [
        [1,  0], [0, -1],
        [0, -1], [1,  0]
    ]
}

It becomes:

            /  1  -i \
1/sqrt(2) * |        |
            \ -i   1 /

Of course, you can just use "RX_90" for this.

Don't try to specify controlled gates by giving the full matrix, because then DQCsim won't detect them properly. Controlled gates are specified as follows.

Controlled gates

To make controlled gates, the above predefined or custom matrices are interpreted as the non-controlled submatrix, automatically extended for the number of control qubits specified in the "controlled" key, which must be a positive integer. If not specified, a non-controlled gate is implied. For example,

{
    "controlled": 1,
    "type": "X",
}

represents a CNOT gate. You can also use the "C-" shorthand in the string notation to do this; just using "C-X" instead of the dictionary is equivalent.

Beware the "global" phase of the submatrix; it matters due to DQCsim synthesizing the controlled matrix by padding at the top-left side with the identity matrix. This is why the difference between "rz" and "phase" exists.

Measurements

"measure" gates by default represent a measurement in the Z basis. You can specify a different Pauli basis by supplying the "basis" key, which must then be "X", "Y", or "Z". Alternatively, you can specify an arbitrary basis by specifying a 2x2 matrix using "matrix". The operation then becomes equivalent to the following:

  • apply a unitary gate to the qubit defined by the Hermitian transpose of the given matrix;
  • measure the qubit in the Z axis;
  • apply a unitary gate to the qubit defined by the given matrix.

Prep gates

"prep" gates, like measurements, default to the Z basis, accept a "basis" key to select a different Pauli basis, or accept a 2x2 matrix, making the operation equivalent to the following:

  • set the state of the qubit to |0>;
  • apply a unitary gate to the qubit defined by the given matrix.

Example file

Here's an example, generated from the QX platform file.

{
    "prep_x": {
        "type": "prep",
        "basis": "x"
    },
    "prep_y": {
        "type": "prep",
        "basis": "y"
    },
    "prep_z": "prep",
    "i": "I",
    "h": "H",
    "x": "X",
    "y": "Y",
    "z": "Z",
    "x90": "RX_90",
    "y90": "RY_90",
    "x180": "RX_180",
    "y180": "RY_180",
    "mx90": "RX_M90",
    "my90": "RY_M90",
    "rx": "RZ",
    "ry": "RY",
    "rz": "RZ",
    "s": "S",
    "sdag": "S_DAG",
    "t": "T",
    "tdag": "T_DAG",
    "cnot": "C-X",
    "toffoli": "C-C-X",
    "cz": "C-Z",
    "swap": "SWAP",
    "measure": "measure",
    "measure_x": {
        "type": "measure",
        "basis": "x"
    },
    "measure_y": {
        "type": "measure",
        "basis": "y"
    },
    "measure_z": "measure"
}

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

dqcsim_openql_mapper-0.0.3-py38-none-manylinux2010_x86_64.whl (484.6 kB view details)

Uploaded Python 3.8 manylinux: glibc 2.12+ x86-64

dqcsim_openql_mapper-0.0.3-py37-none-manylinux2010_x86_64.whl (484.6 kB view details)

Uploaded Python 3.7 manylinux: glibc 2.12+ x86-64

dqcsim_openql_mapper-0.0.3-py36-none-manylinux2010_x86_64.whl (484.6 kB view details)

Uploaded Python 3.6 manylinux: glibc 2.12+ x86-64

dqcsim_openql_mapper-0.0.3-py35-none-manylinux2010_x86_64.whl (484.6 kB view details)

Uploaded Python 3.5 manylinux: glibc 2.12+ x86-64

dqcsim_openql_mapper-0.0.3-py3-none-manylinux2010_x86_64.whl (484.6 kB view details)

Uploaded Python 3 manylinux: glibc 2.12+ x86-64

File details

Details for the file dqcsim_openql_mapper-0.0.3-py38-none-manylinux2010_x86_64.whl.

File metadata

  • Download URL: dqcsim_openql_mapper-0.0.3-py38-none-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 484.6 kB
  • Tags: Python 3.8, manylinux: glibc 2.12+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.20.1 setuptools/45.1.0 requests-toolbelt/0.9.1 tqdm/4.41.1 CPython/3.6.10

File hashes

Hashes for dqcsim_openql_mapper-0.0.3-py38-none-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 208d4342d6657639921c3dd834e0e02826dfd9962e6b806e523847713b053732
MD5 4859ca956f0d72de8465ffed91473088
BLAKE2b-256 79ef1d851be7a6a3b10c350f0915b9a3a51c79f8752ba8ef2642b72467580883

See more details on using hashes here.

File details

Details for the file dqcsim_openql_mapper-0.0.3-py37-none-manylinux2010_x86_64.whl.

File metadata

  • Download URL: dqcsim_openql_mapper-0.0.3-py37-none-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 484.6 kB
  • Tags: Python 3.7, manylinux: glibc 2.12+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.20.1 setuptools/45.1.0 requests-toolbelt/0.9.1 tqdm/4.41.1 CPython/3.6.10

File hashes

Hashes for dqcsim_openql_mapper-0.0.3-py37-none-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 f5d1b8dcb3fc410d25dcc9c48fa48b54385320acccef5134372a99a9bd01445c
MD5 25e029fddbcb7b16e0b87bbe96b0ea4c
BLAKE2b-256 2847823c2f337ba97e8c281e23ed6f55cfa8d6ec31a4d9aec371d416fa5e49a1

See more details on using hashes here.

File details

Details for the file dqcsim_openql_mapper-0.0.3-py36-none-manylinux2010_x86_64.whl.

File metadata

  • Download URL: dqcsim_openql_mapper-0.0.3-py36-none-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 484.6 kB
  • Tags: Python 3.6, manylinux: glibc 2.12+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.20.1 setuptools/45.1.0 requests-toolbelt/0.9.1 tqdm/4.41.1 CPython/3.6.10

File hashes

Hashes for dqcsim_openql_mapper-0.0.3-py36-none-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 cee783efc3d070efb7beca20798de5d1967e5f6265450e1a1d6c86f32cd7a7e9
MD5 807eb2236caed97be2a713248a3407a3
BLAKE2b-256 8672907440a90c3f2c0079ead106d74b6f88363961ad180caa387e4ff22324dd

See more details on using hashes here.

File details

Details for the file dqcsim_openql_mapper-0.0.3-py35-none-manylinux2010_x86_64.whl.

File metadata

  • Download URL: dqcsim_openql_mapper-0.0.3-py35-none-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 484.6 kB
  • Tags: Python 3.5, manylinux: glibc 2.12+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.20.1 setuptools/45.1.0 requests-toolbelt/0.9.1 tqdm/4.41.1 CPython/3.6.10

File hashes

Hashes for dqcsim_openql_mapper-0.0.3-py35-none-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 66669cf2eb9c98423f2ff8b05acca81d057653abdffc6173f08a663f0e1aa3a8
MD5 130bef489f0b467853ef1a5b0bc5e12b
BLAKE2b-256 c9c268e15a2f001831f98bcd2acc405eb18c75b96fa930be96e72e10f4166536

See more details on using hashes here.

File details

Details for the file dqcsim_openql_mapper-0.0.3-py3-none-manylinux2010_x86_64.whl.

File metadata

  • Download URL: dqcsim_openql_mapper-0.0.3-py3-none-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 484.6 kB
  • Tags: Python 3, manylinux: glibc 2.12+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.20.1 setuptools/45.1.0 requests-toolbelt/0.9.1 tqdm/4.41.1 CPython/3.6.9

File hashes

Hashes for dqcsim_openql_mapper-0.0.3-py3-none-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 4d8fea7c96280736633453387dd7fc7db952be71392d7b08af0c0e8bc56e5b68
MD5 35d36212feacb1e8aa0eee13c0c22f67
BLAKE2b-256 53eb1339db8a41dca9204e1744a47f7e1a941ae42e3ccdcf2cdbab34a8318adc

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page