© Vladimir Silva 2018
Vladimir SilvaPractical Quantum Computing for Developershttps://doi.org/10.1007/978-1-4842-4218-6_3

3. Enter the IBM Q Experience: A One-of-a-Kind Platform for Quantum Computing in the Cloud

Vladimir Silva1 
(1)
CARY, NC, USA
 

In this chapter we take a look at quantum computing in the cloud with IBM Q Experience: the first platform of its kind. The chapter starts with an overview of the Composer, the web console used to visually create circuits, submit experiments, explore hardware devices, and more. Next, you will learn how to create your first experiment and submit it to the simulator or real quantum device. IBM Q Experience features a powerful REST API to control the life cycle of the experiment, and this chapter will show you how with detailed descriptions of the end points and request parameters. Finally, the chapter ends with a practical implementation of the official Python library (dubbed IBMQuantumExperience) for Node JS. This custom Node JS library will put your asynchronous Javascript and REST API skills to the test. Let’s get started.

IBM has certainly taken an early lead in the race for quantum computing in the cloud. They came up with a really cool platform to run experiments remotely called the Q Experience. But is it just me or the names of these tools make a lot of analogies to music theory? Check this out: the visual editor used to create quantum circuits is called the Composer. Not weird enough? The quantum circuits built with the editor are called scores (as in a music score), not to mention that visually the editor looks a lot like the written score of a musical composition. I say this because I’ve been playing the classical guitar for a long time and had an eerie familiarity with a guitar score the first time I looked at the Composer (with the gates looking a lot like music notes). Still think I am crazy? The platform is called the Q Experience; have you ever heard about the Jimi Hendrix Experience? Perhaps the Composer is the score workbook where you will create a great masterpiece for the rest of us to enjoy. Quantum computing does have the power to transform the status quo.

Getting Your Feet Wet with IBM Q Experience

Q Experience is IBM’s platform for quantum computing in the cloud, and it is really cool. Let’s take a look (All Reprints Courtesy of International Business Machines Corporation, © International Business Machines Corporation):
../images/469026_1_En_3_Chapter/469026_1_En_3_Fig1_HTML.jpg
Figure 3-1

IBM Q Experience main window

Quantum Composer

The Composer is the visual tool used to create your quantum circuits or scores. At the top it shows the experiment histogram with the qubits available for use (see Figure 3-2).
../images/469026_1_En_3_Chapter/469026_1_En_3_Fig2_HTML.jpg
Figure 3-2

Experiment Composer

  • On the left side of the histogram, we see 5 qubits available from processor ibmqx4. They are all initialized to the ground state |0>. The line at the bottom is the measurement line where the results of the circuit will be collected. Remember that measurement should be the last thing done in the circuit as all gate operations execute in parallel and in superimposed states.

  • On the right side, we have the quantum gates. Drag gates into the histogram location of a specific qubit to start building a circuit.

Let’s look at the gates and their meaning.

Quantum Gates

The quantum gates supported by IBM Q Experience are described in Table 3-1.
Table 3-1

Quantum Gates for IBM Q Experience

Gate

Description

Pauli X

../images/469026_1_En_3_Chapter/469026_1_En_3_Figa_HTML.jpg

It rotates the qubit 180 degrees in the X-axis. Maps |0> to |1> and |1> to |0>. Also it is known as the bit flip or NOT gate. It is represented by the matrix:

$$ X=\left[\begin{array}{cc}0& 1\\ {}1& 0\end{array}\right] $$

Pauli Y

../images/469026_1_En_3_Chapter/469026_1_En_3_Figb_HTML.jpg

It rotates around the Y-axis of the Bloch sphere by π radians. It is represented by the Pauli matrix:

$$ Y=\left[\begin{array}{cc}0& -i\\ {}-i& 0\end{array}\right] $$

where $$ i=\sqrt{-1} $$ is known as the imaginary unit.

Pauli Z

../images/469026_1_En_3_Chapter/469026_1_En_3_Figc_HTML.jpg

It rotates around the Z-axis of the Bloch sphere by π radians. It is represented by the Pauli matrix:

$$ Z=\left[\begin{array}{cc}1& 0\\ {}0& -1\end{array}\right] $$

Hadamard

../images/469026_1_En_3_Chapter/469026_1_En_3_Figd_HTML.jpg

It represents a rotation of π on the axis $$ \left(X+Z\right)/\sqrt{2} $$. In other words, it maps the states:

 • |0> to $$ \left(|0>+|1>\right)/\kern0.5em \sqrt{2} $$

 • |1> to $$ \left(|0>-|1>\right)/\kern0.5em \sqrt{2} $$

This gate is required to make superpositions.

Phase $$ \sqrt{Z} $$

../images/469026_1_En_3_Chapter/469026_1_En_3_Fige_HTML.jpg

It has the property that it maps X→Y and Z→Z. This gate extends H to make complex superpositions.

Transposed conjugate of S

../images/469026_1_En_3_Chapter/469026_1_En_3_Figf_HTML.jpg

It maps X→-Y and Z→Z.

Controlled NOT (CNOT)

../images/469026_1_En_3_Chapter/469026_1_En_3_Figg_HTML.jpg

This is a 2-qubit gate that flips the target qubit (applies Pauli X) if the control is in state 1. This gate is required to generate entanglement.

Phase $$ \sqrt{S} $$

../images/469026_1_En_3_Chapter/469026_1_En_3_Figh_HTML.jpg

The $$ \sqrt{S} $$ gate performs halfway of a 2-qubit swap. It is universal such that any quantum multi-qubit gate can be constructed from only sqrt(swap) and single-qubit gates. It is represented by the matrix:

$$ \sqrt{S}=\left[\begin{array}{cccc}1& 0& 0& 0\\ {}0& 1/2\left(1+i\right)& 1/2\left(1-i\right)& 0\\ {}0& 1/2\left(1-i\right)& 1/2\left(1+i\right)& 0\\ {}0& 0& 0& 1\end{array}\right] $$

Transposed conjugate of T or T-dagger

../images/469026_1_En_3_Chapter/469026_1_En_3_Figi_HTML.jpg

Represented by the matrix:

$$ \sqrt{S}=\left[\begin{array}{cccc}1& 0& 0& 0\\ {}0& 1/2\left(1-i\right)& 1/2\left(1+i\right)& 0\\ {}0& 1/2\left(1+i\right)& 1/2\left(1-i\right)& 0\\ {}0& 0& 0& 1\end{array}\right] $$

Barrier

../images/469026_1_En_3_Chapter/469026_1_En_3_Figj_HTML.jpg

It prevents transformations across its source line.

Measurement

../images/469026_1_En_3_Chapter/469026_1_En_3_Figk_HTML.jpg

The measurement gate takes a qubit in a superposition of states as input and spits either a 0 or 1. Furthermore, the output is not random. There is a probability of a 0 or 1 as output which depends on the original state of the qubit.

Conditional

../images/469026_1_En_3_Chapter/469026_1_En_3_Figl_HTML.jpg

Conditionally apply a quantum operation.

Physical partial rotation (U gates)

../images/469026_1_En_3_Chapter/469026_1_En_3_Figm_HTML.jpg

U1: It is a one parameter single-qubit phase gate with zero duration.

U2: It is a two-parameter single-qubit gate with duration of one unit of gate time.

U3: It is a three-parameter single-qubit gate with duration of two units of gate time.

Identity

../images/469026_1_En_3_Chapter/469026_1_En_3_Fign_HTML.jpg

The identity gate performs an idle operation on the qubit for a time equal to one unit of time.

You can drag gates from the right side of the Composer to create a circuit, or if you prefer to write assembly code, you can switch to the QASM editor mode as shown in Figure 3-3.
../images/469026_1_En_3_Chapter/469026_1_En_3_Fig3_HTML.jpg
Figure 3-3

Experiment editor in QASM editor mode

Tip

QASM is the quantum assembly language, built on top of the OPENQASM platform, and it is used to implement experiments with low-depth quantum circuits. Even though assembler has become something of a lost art, some people may find its raw power more appealing than the Python SDK or even the visual editor.

Now let’s take a look at the various quantum processors available for use.

Quantum Backends Available for Use

There are a few quantum processors to choose from for experimentation. Table 3-2 shows the official list ranked by the number of qubits according to the IBM Q Experience backend information site.1
Table 3-2

Official List of Quantum Backends Available for IBM Q Experience Users

Name

Details

Ibmqx2

Code Name: Sparrow

Qubits: 5

Online since January 24, 2017

Ibmqx4

Code Name: Raven

Qubits: 5

Online since September 25, 2017

Ibmqx3

Code Name: Albatross

Qubits: 16

Online since June 2017

Ibmqx5

Code Name: Albatross

Qubits: 16

Online since online September 28, 2017

This device is reconfigured version of ibmqx3.

Table 3-2 shows the official list of processors available for use at the time of this writing, but there is a much interesting way to get an updated list of available machines in real time using the excellent REST API. This API is described in more detail on the “Remote Access via the REST API” section in this chapter, but for now let’s demonstrate how to obtain an always up-to-date list of backends using the Available Backend List REST end point:

https://quantumexperience.ng.bluemix.net/api/Backends?access_token=ACCESS-TOKEN

Tip

To obtain an access token, see the section “Authentication via API Token” under “Remote Access via the REST API” of this chapter. Note that an API token is not the same as an access token. API tokens are used to execute quantum programs via the Python SDK. Access tokens are used to invoke the REST API.

The URL in the previous paragraph returns a list of quantum processors in JSON format. This is what it looks like by the time of this writing. Note that your results may be different:
[{
  "name": "ibmqx2",
  "version": "1",
  "status": "on",
  "serialNumber": "Real5Qv2",
  "description": "5 transmon bowtie",
  "basisGates": "u1,u2,u3,cx,id",
  "onlineDate": "2017-01-10T12:00:00.000Z",
  "chipName": "Sparrow",
  "id": "28147a578bdc88ec8087af46ede526e1",
  "topologyId": "250e969c6b9e68aa2a045ffbceb3ac33",
  "url": "https://ibm.biz/qiskit-ibmqx2",
  "simulator": false,
  "nQubits": 5,
  "couplingMap": [
    [0, 1],
    [0, 2],
    [1, 2],
    [3, 2],
    [3, 4],
    [4, 2]
  ]
}, {
  "name": "ibmqx5",
  "version": "1",
  "status": "on",
  "serialNumber": "ibmqx5",
  "description": "16 transmon 2x8 ladder",
  "basisGates": "u1,u2,u3,cx,id",
  "onlineDate": "2017-09-21T11:00:00.000Z",
  "chipName": "Albatross",
  "id": "f451527ae7b9c9998e7addf1067c0df4",
  "topologyId": "ad8b182a0653f51dfbd5d66c33fd08c7",
  "url": "https://ibm.biz/qiskit-ibmqx5",
  "simulator": false,
  "nQubits": 16,
  "couplingMap": [
    [1, 0],
    ...
    [15, 14]
  ]
}, {
  "name": "Device Real5Qv1",
  "status": "off",
  "serialNumber": "Real5Qv1",
  "description": "Device Real5Qv1",
  "id": "cc7f910ff2e6860e0d4918e9ee0ebae0",
  "topologyId": "250e969c6b9e68aa2a045ffbceb3ac33",
  "simulator": false,
  "nQubits": 5,
  "couplingMap": [
    [0, 1],
    [0, 2],
    [1, 2],
    [3, 2],
    [3, 4],
    [4, 2]
  ]
}, {
  "name": "ibmqx_hpc_qasm_simulator",
  "status": "on",
  "serialNumber": "hpc-simulator",
  "basisGates": "u1,u2,u3,cx,id",
  "onlineDate": "2017-12-09T12:00:00.000Z",
  "id": "084e8de73c4d16330550c34cf97de3f2",
  "topologyId": "7ca1eda6c4bff274c38d1fe66c449dff",
  "simulator": true,
  "nQubits": 32,
  "couplingMap": "all-to-all"
}, {
  "name": "ibmqx4",
  "version": "1",
  "status": "on",
  "serialNumber": "ibmqx4",
  "description": "5 qubits transmon bowtie chip 3",
  "basisGates": "u1,u2,u3,cx,id",
  "onlineDate": "2017-09-18T11:00:00.000Z",
  "chipName": "Raven",
  "id": "c16c5ddebbf8922a7e2a0f5a89cac478",
  "topologyId": "3b8e671a5a3b56899e6e601e6a3816a1",
  "url": "https://ibm.biz/qiskit-ibmqx4",
  "simulator": false,
  "nQubits": 5,
  "couplingMap": [
    [1, 0],
    [2, 0],
    [2, 1],
    [2, 4],
    [3, 2],
    [3, 4]
  ]
}, {
  "name": "ibmqx3",
  "version": "1",
  "status": "off",
  "serialNumber": "ibmqx3",
  "description": "16 transmon 2x8 ladder",
  "basisGates": "u1,u2,u3,cx,id",
  "onlineDate": "2017-06-06T11:00:00.000Z",
  "chipName": "Albatross",
  "id": "2bcc3cdb587d1bef305ac14447b9b0a6",
  "topologyId": "db99eef232f426b45d2d147359580bc6",
  "url": "https://ibm.biz/qiskit-ibmqx3",
  "simulator": false,
  "nQubits": 16,
  "couplingMap": [
  ...
  ]
}, {
  "name": "QS1_1",
  "version": "1",
  "status": "standby",
  "serialNumber": "QS1_1",
  "description": "20 qubit device v1",
  "basisGates": "SU2+CNOT",
  "onlineDate": "2017-10-20T11:00:00.000Z",
  "chipName": "Qubert",
  "id": "cb141f7bb641b8a10487a6fab8483b86",
  "topologyId": "25197b9b73c4b52ca713ca4d126417b5",
  "simulator": false,
  "nQubits": 20,
  "couplingMap": [
  ...
  ]
}, {
  "name": "ibmqx_qasm_simulator",
  "status": "on",
  "description": "online qasm simulator",
  "basisGates": "u1,u2,u3,cx,id",
  "id": "18da019106bf6b5a55e0ef932763a670",
  "topologyId": "250e969c6b9e68aa2a045ffbceb3ac33",
  "simulator": true,
  "nQubits": 24,
  "couplingMap": "all-to-all"
}]
Listing 3-1

HTTP Response from the Backend Information REST API Call

Listing 3-1 shows the current list of available processors which mostly matches the official list from the IBM Q Experience web site. However, there is a lot of extra interesting information about the structural layout of these machines:
  • Extra processors and simulators:
    • It looks like there are two remote simulators available for use (ibmqx_qasm_simulator, ibmqx_hpc_qasm_simulator) even though the official documentation mentions only one: ibmqx_qasm_simulator. This information can come in handy when testing complex circuits: more simulators are always a good thing.

    • Rumors of a 20-qubit processor have been swirling around for some time. There is even talk of an upcoming 50-qubit monster processor by the end of 2018. This list seems to confirm the 20-qubit machine at least. But don’t get excited just yet; this machine is only available for corporate customers.

  • Besides the usual information such as machine name, version, status, number of qubits, and others, there are some terms we should be familiarized with:
    • basisGates : These are the physical qubit gates of the processor. They are the foundation under which more complex logical gates can be constructed. Most of the processors in the list use u1, u2, u3, cx, id.
      • Gates u1, u2, u3 are called partial NOT gates and perform rotations on axes X, Y, Z by theta, phi, or lambda radians of a qubit.

      • Cx is called the controlled NOT gate (CNOT or CX). It acts on 2 qubits and performs the NOT operation on the second qubit only when the first qubit is |1> and otherwise leaves it unchanged.

      • Id is the identity gate which performs an idle operation on a qubit for one unit of time.

    • couplingMap: The coupling map defines interactions between individual qubits while retaining quantum coherence (or a pure state – imagine a peloton of soldiers breaking step when crossing an old bridge so that the amplitude of their feet hitting the ground does not add up and destroy the bridge). Qubit coupling is used to simplify quantum circuitry and allow the system to be broken up into smaller units.

Now back to the Composer for our first quantum composition.

Opus 1: Variations on Bell and GHZ States

This composition is a weird one. Here we look at two mind-bending quantum experiments used to demonstrate the weirdness of quantum mechanics :
  • Bell states: They demonstrate that physics are not described by local reality. This is what Einstein called spooky action at a distance.

  • GHZ states: Even stranger than Bell states, GHZ states (named after their creators: Greenberger-Horne-Zeilinger) are the 3-qubit generalization of the Bell states.

Let’s look at them in more detail.

Bell States and Spooky Action at a Distance

Bell states are the experimental test of the famous Bell inequalities. In 1964 Irish physicist John Bell proposed a way to put quantum entanglement (spooky action at a distance) to the test. He came up with a set of inequalities which have become incredibly important in the physics community. This set of inequalities is known as Bell’s theorem, and it goes something like this.

Consider photon polarization (when light oscillates in a specific plane) at three different angles A = 0, B = 120, and C = 240. Realism says that a photon has definite simultaneous values for these three polarization settings, and they must correspond to the eight cases shown in Table 3-3.
Table 3-3

Permutations for Photon Polarizations at Three Angles

Count

A(0)

B(120)

C(240)

[AB]

[BC]

[AC]

Sum

Average

1

A+

B+

C+

1(++)

1(++)

1(++)

3

1

2

A+

B+

C–

1(++)

0

0

1

1/3

3

A+

B–

C+

0

0

1(++)

1

1/3

4

A+

B–

C–

0

1(−−)

0

1

1/3

5

A−

B+

C+

0

1(++)

0

1

1/3

6

A−

B+

C−

0

0

1(−−)

1

1/3

7

A−

B−

C+

1(−−)

0

0

1

1/3

8

A−

B−

C−

1(−−)

1(−−)

1(−−)

3

1

Now Bell’s theorem asks: what is the probability that the polarization at any neighbor will be the same as the first? We also calculate the sum and average of the polarizations. Assuming realism is true, then by looking at Table 3-3, the answer to the question is the probability must be >= 1/3. This is what Bell’s inequality gives: a means to put this assertion to the test. Here is the incredible part: believe it or not, quantum mechanics violates Bell’s inequality giving probabilities less than 1/3. This was proven experimentally for the first time in 1982 French physicist Alain Aspect.

Tip

A more detailed description of Aspect’s experiment and Bell’s inequality is described in Chapter 1, EPR Paradox Defeated: Bohr Has the Last Laugh.

So now let’s translate the photon polarization from the preceding text into an experiment that can be run in a quantum computer. In 1969 John Clauser, Michael Horne, Abner Shimony, and Richard Holt came up with a proof for Bell’s theorem: the CHSH inequality which formally states
$$ S=\left\langle A,B\right\rangle -\left\langle A,{B}^{\prime}\right\rangle +\left\langle {A}^{\prime },B\right\rangle +\left\langle {A}^{\prime },{B}^{\prime}\right\rangle $$
$$ S\le 2 $$
To illustrate this, we have two detectors: Alice and Bob. Given A and A′ are detector settings on side Alice, B and B′ on side Bob, with the four combinations being tested in separate experiments. Realism says that for a pair of entangled particles, the parity table showing all possible permutations looks as shown in the following table:

A

B

1

A

B'

0

A'

B

0

A'

B'

1

In classical realism, the CHSH inequality becomes |S| = 2. However, the mathematical formalism of quantum mechanics predicts a maximum value for S of |S|=$$ 2\sqrt{2} $$, thus violating this inequality. This can be put to the test using four separate quantum circuits (one per measurement) with 2 qubits each. To simplify things, let measurements on Alice detector be A = Z and Aʹ = X, and Bob’s detector B = W and Bʹ = V (see Table 3-4). To begin the experiment, a basis Bell state must be constructed which matches the identity (see Figure 3-4):
$$ 1/\sqrt{2}\left(|00+|11\right) $$
The preceding expression essentially means the qubit held by Alice can be 0 or 1. If Alice measured her qubit in the standard basis, the outcome would be perfectly random, either possibility having probability 1/2. But if Bob then measured his qubit, the outcome would be the same as the one Alice got. So, if Bob measured, he would also get a random outcome on first sight, but if Alice and Bob communicated, they would find out that, although the outcomes seemed random, they are correlated.
../images/469026_1_En_3_Chapter/469026_1_En_3_Fig4_HTML.jpg
Figure 3-4

Basis Bell state

In Figure 3-4, 2 qubits are prepared in the ground state |0>. The H gate creates a superposition of the first qubit to the state $$ 1/\sqrt{2}\left(|00+|10\right) $$. Next the CNOT gate flips the second qubit if the first is excited, making the state $$ 1/\sqrt{2}\left(|00+|11\right) $$. This is the initial entangled state required for the four measurements in Table 3-4 (All reprints courtesy of International Business Machines Corporation, © International Business Machines Corporation).
  • To rotate the measurement basis to the ZW axis, use the sequence of gates S-H-T-H.

  • To rotate the measurement basis to the ZV axis, use the sequence of gates S-H-T’-H.

  • The XW and XV measurement is performed the same way as in the preceding text and the X via a Hadamard gate before a standard measurement.

Tip

Before performing the experiment in the Composer, make sure its topology (the number of qubits and target device) in the score is set to 2 over a simulator. Some topologies (like the 5 qubits in a real quantum device) do not support entanglement for qubits 0 and 1 giving errors at design. Note that the target device can be a real quantum processor or a simulator. All in all, as long as you use a simulator, you should be fine.

Table 3-4

Quantum Circuits for Bell States

Bell state measurement

Result for 100 shots

AB (ZW)

../images/469026_1_En_3_Chapter/469026_1_En_3_Figo_HTML.jpg

c[2]

Probability

11

0.39

10

0.06

00

0.46

01

0.09

AB′ (ZV)

../images/469026_1_En_3_Chapter/469026_1_En_3_Figp_HTML.jpg

c[2]

Probability

11

0.49

10

0.07

00

0.36

01

0.08

A′B (XW)

../images/469026_1_En_3_Chapter/469026_1_En_3_Figq_HTML.jpg

c[2]

Probability

11

0.42

10

0.05

00

0.49

01

0.04

A′B′ (XV)

../images/469026_1_En_3_Chapter/469026_1_En_3_Figr_HTML.jpg

c[2]

Probability

11

0.05

10

0.52

00

0.03

01

0.40

Now we need to construct a table with the results of each measurement plus the correlation probability between A and B <AB>. The sum of the probabilities for the parity of the entangled particles is given by
$$ \left\langle AB\right\rangle =P\left(1,1\right)+P\left(0,0\right)-P\left(1,0\right)-P\left(0,1\right) $$
Remember that the ultimate goal is to determine if S ≤ 2 or |S| = 2; thus by compiling the results of all measurements, we obtain Table 3-5.
Table 3-5

Compiled Results from the Bell Experiment

 

P(00)

P(11)

P(01)

P(10)

<AB>

AB (ZW)

0.46

0.39

0.09

0.06

0.68

AB′ (ZV)

0.36

0.49

0.08

0.07

0.73

A′B (XW)

0.49

0.42

0.04

0.05

0.47

A′B′(XV)

0.03

0.05

0.4

0.52

−0.32

Add the absolute values of column <AB> and we obtain |S| = 2.2. These results violate Bell’s inequality (as predicted by quantum mechanics) and are pretty close to the official tests performed on May 2, 2017, by IBM scientists over 8192 shots.2 How about yours?

Even Spookier: GHZ States Tests

These are named after physicists Greenberger-Horne-Zeilinger who came up with a generalization test for N entangled qubits with the simplest being a 3-qubit GHZ state:
$$ \left| GHZ\right\rangle =1/\sqrt{2}\left(\left|000\right\rangle -\left|111\right\rangle \right) $$

Note

The importance of the GHZ states is that they show that the entanglement of more than two particles is in conflict with local realism not only for statistical (probabilistic) but also nonstatistical (deterministic) predictions.

In simple terms GHZ states show a stronger violation of Bell’s inequality. Let’s see how with a simple puzzle: imagine three independent boxes each containing two variables X and Y. Each variable has two possible outcomes: 1 and –1. The question is to find a set of values for X and Y that solves the following set of identities :
(1)   XYY = 1
(2)   YXY = 1
(3)   YYX = 1
(4)   XXX = –1
For the impatient out there, there is no solution for this. For example, replace Y = 1 in (1), (2), and (3), and then multiply them, that is, (5) = (1) * (2) * (3). The set then becomes
(1)   X11 = 1
(2)   1X1 = 1
(3)   11X = 1
(4)   XXX = –1
(5)   Multiply (1) (2) (3) and we get XXX = 1

There is no solution because identity (4) XXX = –1 contradicts identity (5) XXX = 1. The scary part is that a GHZ state can indeed provide a solution to this problem, which seems impossible in the deterministic view of classical reality, but nothing is impossible in the world of quantum mechanics, just improbable.

Incredibly, GHZ tests can rule out the local reality description with certainty after a single run of the experiment, but first we must construct a GHZ basis state.

Table 3-6. Basis GHZ State

../images/469026_1_En_3_Chapter/469026_1_En_3_Figs_HTML.jpg

To kick-start the experiment, the basis GHZ state (as well as probability results which should be around half) is shown in Table 3-6:
  1. 1.

    In the basis circuit, Hadamard gates in qubits 1 and 2 put them in superposition |00,01,01,11>. At the same time, the X gate negates qubit 3; thus we end up with the states $$ 1/\sqrt{2}\left(\left|001\right\rangle +\left|101\right\rangle +\left|011\right\rangle +\left|111\right\rangle \right) $$.

     
  2. 2.

    The two CNOT gates entangle all qubits into the state $$ 1/\sqrt{2}\left(\left|001\right\rangle +\left|010\right\rangle +\left|100\right\rangle +\left|111\right\rangle \right) $$.

     
  3. 3.

    Finally the three Hadamard gates map step 2 to the state ½(| 000⟩ − | 111⟩).

     
Now, create the quantum circuits for identities XYY, YXY, XYY, and XXX from the previous section as shown in Table 3-7 (All reprints courtesy of International Business Machines Corporation, © International Business Machines Corporation).
Table 3-7

Quantum Circuits for GHZ States

Measurement

Results for 100 shots

YYX

../images/469026_1_En_3_Chapter/469026_1_En_3_Figt_HTML.jpg

c[3]

Probability

011

0.34

101

0.23

110

0.23

000

0.20

YXY

../images/469026_1_En_3_Chapter/469026_1_En_3_Figu_HTML.jpg

c[3]

Probability

011

0.23

101

0.28

110

0.25

000

0.24

XYY

../images/469026_1_En_3_Chapter/469026_1_En_3_Figv_HTML.jpg

c[3]

Probability

011

0.23

101

0.26

110

0.35

000

0.16

XXX

../images/469026_1_En_3_Chapter/469026_1_En_3_Figw_HTML.jpg

c[3]

Probability

010

0.25

100

0.32

111

0.22

001

0.21

  • For the measurement of X, apply the H gate to the corresponding qubit.

  • For each instance of Y, apply the S (S-dagger), and H gates to the corresponding qubit.

Finally compare the results of the preceding experiment against the official data from IBM Q Experience.3 How do your results stack up? All in all, the principles of quantum mechanics shown in this section have been challenged by a theory called super determinism which gives a way out.

Super Determinism: A Way Out of the Spookiness. Was Einstein Right All Along?

In an interview for BBC in 1969, physicist John Bell talked about his work on quantum mechanics. He said that we must accept the predictions that actions are transferred faster than the speed of light between entangled particles but at the same time we cannot do anything with it. Information cannot travel faster than the speed of light, a fact that is also predicted by quantum mechanics. As if nature is playing a trick on us. He also mentioned that there is a way out of this riddle through a principle called super determinism.

Particle entanglement implies that measurements performed in one particle affect the other instantaneously, even across large distances (think opposite sides of the galaxy or the universe), even across time. Einstein was an ardent opponent of this theory famously writing to Niels Bohr God does not throw dice. He could not accept the probabilistic nature of quantum mechanics, so in 1935, along with colleagues Podolsky and Rosen, they came up with the infamous EPR paradox to challenge its foundation. In the EPR paradox, if two entangled particles are separated by a tremendous distance, a measurement in one could not affect the other instantaneously as the event will have to travel faster than the speed of light (the ultimate speed limit in the universe). This will violate general relativity, thus creating a paradox: Nothing travels faster than the speed of light, that is, the absolute rule of relativity.

Nevertheless, in 1982 the predictions of quantum mechanics were confirmed by French physicist Alain Aspect. He devised an experiment that showed Bell’s inequality is violated by entangled photons. He also proved that a measurement in one of the entangled photons travels faster than the speed of light to signal its state to the other. Since then, Aspect’s results have been proven correct time and again (details on his experiment is shown in Chapter 1). The irony is that there is a chance that Einstein was right all along and entanglement is just an illusion. It is the principle of super determinism.

Tip

In simple terms super determinism says that freedom of choice has been removed since the beginning of the universe. All particle correlations and entanglements were established at the moment of the Big Bang. Thus there is no need for a faster-than-light signal to tell particle B what the outcome of particle A is.

If true, this loophole will prove that Einstein was right when postulating the EPR paradox and all our hard work in quantum programing is just an illusion. But this principle sounds more like religious dogma (all outcomes determined by fate) than science as Bell argued that super determinism was implausible. His reasoning being that freedom of choice is effectively free for the purpose at hand due to alterations introduced by a large number of very small effects. Super determinism has been called untestable as experimenters would never be able to eliminate correlations that were created at the beginning of the universe. Nevertheless this hasn’t stopped scientists on trying to prove Einstein right and particle entanglement an illusion. As a matter of fact, there is an experiment hard at work to settle things up and is really inventive. Let’s see how.
../images/469026_1_En_3_Chapter/469026_1_En_3_Fig5_HTML.jpg
Figure 3-5

Bell’s inequality experiment using cosmic photons vs. the standard test

Figure 3-5 shows the standard Bell’s inequality test experiment (at the bottom) and a variation of the experiment using cosmic photons (at the top) by Andrew Friedman and colleagues at MIT.4

Tip

For a full description of the standard Bell’s inequality test, see Chapter 1, EPR Paradox Defeated: Bohr Has the Last Laugh.

Friedman and colleagues came up with a novel variation of the standard Bell experiment using cosmic rays. The idea is to use real-time astronomical observations of distant stars in our own galaxy, distant quasars, or patches of the cosmic microwave background, to essentially let the universe decide how to set up the experiment instead of using a standard quantum random number generator. That is, photons from the distant galaxies are used to control the orientation of the polarization filters just prior to the arrival of entangled photons.

If successful, the implications would be groundbreaking. If the results from such experiment do not violate Bell’s inequality, it would mean that super determinism could be true after all. Particle entanglement will be an illusion, and signal transfer between entangled particles could not travel faster than light as predicted by relativity. Einstein will be right and there is no spooky action at a distance.

Luckily for us, fans of quantum mechanics, no such thing has happened so far. Keep in mind that Friedman and colleagues are not the only team getting it on the action. There are multiple teams trying to crack this riddle. As a matter of fact, most of their results agree with quantum mechanics. That is, their results violate Bell’s inequality. So it seems that the rift created by Einstein and Bohr in their struggle between relativity and quantum mechanics long ago is alive and well. My money is in quantum mechanics though. Moving on, the next section shows how IBM Q Experience can be accessed remotely via its slick REST API.

Remote Access via the REST API

Q Experience features a relatively unknown REST API that handles all remote communications behind the scenes. It is used by the current Python SDKs:
  • QISKit : The Quantum Information Software Kit is the de facto access tool for quantum programming in Python.

  • IBMQExperience : A lesser known library bundled with QISKit that wraps the REST API in a Python client.

In this section we peek inside IBMQExperience and look at the different REST end points for remote access. But first, authentication is required.

Authentication

To invoke any REST API call, we must first obtain an access token. This will be the access key to invoke any of the calls in this section. Note that the access token is not the same as the API token (the API token is used to execute quantum programs in Python). There are two ways of obtaining an access token:
  • Using your API token: To obtain the API token, log in to the IBM Q Experience console and follow the instructions in the following section.

  • Using your account username and password: Let’s see how this is done using REST.

Tip

To obtain your API token, log in to the IBM Q Experience console, click your username ➤ My Account, and then click the Advanced tab on the upper right. Finally click Generate and then Copy API Token (see Figure 3-6). Always keep your token secure.

../images/469026_1_En_3_Chapter/469026_1_En_3_Fig6_HTML.jpg
Figure 3-6

Obtain your API token from the console

Authentication via API Token

Authentication via User-Password

The response for both methods is
{
  "id": "ACCESS_TOKEN",
  "ttl": 1209600,
  "created": "2018-04-15T20:21:03.204Z",
  "userId": "USER-ID"
}

Where id is your access token, ttl is the time to live (or expiration time) in milliseconds, and userId is your user id. Save the access token and the user id for use in this section. Note that when your session expires, a new access token needs to be generated.

List Available Backends

This call returns a JSON list of all available backends and simulators in IBM Q Experience:

Request Parameters

Name

Value

access_token

Your account access token

HTTP Headers

Name

Value

x-qx-client-application

Defaults to qiskit-api-py

Response Sample

The response content type for all API calls is application/json. The next paragraph shows the partial result of a call to this end point. Note that this end point will return both real processors and simulators.
[{
      "name": "ibmqx2",
      "version": "1",
      "status": "on",
      "serialNumber": "Real5Qv2",
      "description": "5 transmon bowtie",
      "basisGates": "u1,u2,u3,cx,id",
      "onlineDate": "2017-01-10T12:00:00.000Z",
      "chipName": "Sparrow",
      "id": "28147a578bdc88ec8087af46ede526e1",
      "topologyId": "250e969c6b9e68aa2a045ffbceb3ac33",
      "url": "https://ibm.biz/qiskit-ibmqx2",
      "simulator": false,
      "nQubits": 5,
      "couplingMap": [
            [0, 1],
            [0, 2],
            [1, 2],
            [3, 2],
            [3, 4],
            [4, 2]
      ]
},..]
The most important keys from the preceding response are described in Table 3-8.
Table 3-8

Available Backend Response Keys

Key

Description

Name

The name id of the processor to be used when executing code against it.

Version

A string or positive integer probably used to track changes to the processor.

Description

This is probably a description of the hardware used to build the chip. You may see things like:

 • 5 transmon bowtie

 • 16 transmon 2x8 ladder

Note: a transmon is defined as a type of noise-resistant superconducting charge qubit. It was developed by Robert J. Schoelkopf, Michel Devoret, Steven M. Girvin, and their colleagues at Yale University in 2007.5

basisGates

These are the physical qubit gates of the processor. They are the foundation under which more complex logical gates can be constructed.

nQubits

The number of qubits used by the processor.

couplingMap

The coupling map defines interactions between individual qubits while retaining quantum coherence. It is used to simplify quantum circuitry and allow the system to be broken up into smaller units.

Get Calibration Information for a Given Processor

This call returns a JSON list of the calibration parameters for a given processor in Q Experience. These parameters are documented in detail in the IBMQX backend information site.6

Request Parameters

Name

Value

access_token

Your account access token.

HTTP Headers

Name

Value

x-qx-client-application

Defaults to qiskit-api-py (a default value for the official client although I suspect it can be anything).

Response Sample

Qubits are highly sensitive to error and environmental noise. Calibration information gives an overview of the quality of the qubits inside the processor. Listing 3-2 shows a simplified response of the calibration parameters for ibmqx4. Some of the most remarkable parameters are
  • gateError: This is the error rate of a qubit gate operation at a given time.

  • readoutError: This is the error rate of a qubit readout operation at a given time.

Tip

Qubit quality evaluation involves four stages (operations): preparation, memory, gates, and readout. Error rates are calculated at the gate and readout stages to track the quality of the qubit. This is the information returned by this API call. Note that after usage qubits must be reset (cooled down) to a basis state.

{
      "lastUpdateDate": "2018-04-15T10:47:03.000Z",
      "qubits": [{
            "gateError": {
                  "date": "2018-04-15T10:47:03Z",
                  "value": 0.0012019552727863259
            },
            "name": "Q0",
            "readoutError": {
                  "date": "2018-04-15T10:47:03Z",
                  "value": 0.049
            }
      }, ...
],
      "multiQubitGates": [{
            "qubits": [1, 0],
            "type": "CX",
            "gateError": {
                  "date": "2018-04-15T10:47:03Z",
                  "value": 0.03024023736391171
            },
            "name": "CX1_0"
      },...
]}
Listing 3-2

Simplified Response for the Calibration Parameters If ibmqx4

The information in Listing 3-2 can be seen under the IBM Q Experience console Devices tab on the main menu (see Figure 3-7). Get the calibration information via REST, and compare it against the web console (Reprint courtesy of International Business Machines Corporation, © International Business Machines Corporation).
../images/469026_1_En_3_Chapter/469026_1_En_3_Fig7_HTML.jpg
Figure 3-7

Calibration information reported by the web console

Get Backend Parameters

This call returns a JSON list of the backend parameters for a given processor in Q Experience. Some of these parameters include
  • Qubit cooldown temperature in Kelvin degrees: For example, I got 0.021 K for ibmqx4 – that is, a super frosty –459.6 °F or –273.1 °C.

  • Buffer times in ns.

  • Gate times in ns.

  • Other quantum specs documented in more detail at the backend information site.7

Request Parameters

Name

Value

access_token

Your account access token

HTTP Headers

Name

Value

x-qx-client-application

Defaults to qiskit-api-py

Response Sample

Listing 3-3 shows a simplified response for ibmqx4 parameters in JSON.
{
      "lastUpdateDate": "2018-04-15T10:47:03.000Z",
      "fridgeParameters": {
            "cooldownDate": "2017-09-07",
            "Temperature": {
                  "date": "2018-04-15T10:47:03Z",
                  "value": 0.021,
                  "unit": "K"
            }
      },
      "qubits": [{
            "name": "Q0",
            "buffer": {
                  "date": "2018-04-15T10:47:03Z",
                  "value": 10,
                  "unit": "ns"
            },
            "gateTime": {
                  "date": "2018-04-15T10:47:03Z",
                  "value": 50,
                  "unit": "ns"
            },
            "T2": {
                  "date": "2018-04-15T10:47:03Z",
                  "value": 16.5,
                  "unit": "μs"
            },
            "T1": {
                  "date": "2018-04-15T10:47:03Z",
                  "value": 45.2,
                  "unit": "μs"
            },
            "frequency": {
                  "date": "2018-04-15T10:47:03Z",
                  "value": 5.24208,
                  "unit": "GHz"
            }
      },..]
Listing 3-3

Simplified Response for ibmqx4 Parameters

Get the Status of a Processor’s Queue

This call returns the status of a specific quantum processor event queue .

Request Parameters

It seems strange but this API call appears not to ask for an access token.

HTTP Headers

Name

Value

x-qx-client-application

Defaults to qiskit-api-py

Response Sample

For example, to get the event queue for ibmqx4, paste the following URL in your browser:

https://quantumexperience.ng.bluemix.net/api/Backends/ibmqx4/queue/status

The response looks like {"state":true,"status":"active","lengthQueue":0} where
  • state: It is the status of the processor. If alive, true else false.

  • status: It is the status of the execution queue – active or busy.

  • lengthQueue: It is the size of the execution queue or the number of simulations waiting to be executed.

Tip

When you submit an experiment to IBM Q Experience, it will enter an execution queue. This API call is useful to monitor how busy the processor is at a given time.

List Jobs in the Execution Queue

This call returns a list of jobs in the processor execution queue.

Request Parameters

Name

Value

access_token

Your account access token.

filter

A result size hint in JSON. For example, {“limit”:2} returns a maximum of two entries.

HTTP Headers

Name

Value

x-qx-client-application

Defaults to qiskit-api-py

Response Sample

Listing 3-4 shows the response format for this call. The information appears to be a historical record of experiment executions containing information such as status, dates, results, code, calibration, and more.
[{
      "qasms": [{
            "qasm": "...",
            "status": "DONE",
            "executionId": "331f15a5eed1a4f72aa2fb4d96c75380",
            "result": {
                  "date": "2018-04-05T14:25:37.948Z",
                  "data": {
                        "creg_labels": "c[5]",
                        "additionalData": {
                              "seed": 348582688
                        },
                        "time": 0.0166247,
                        "counts": {
                              "11100": 754,
                              "01100": 270
                        }
                  }
            }
      }],
      "shots": 1024,
      "backend": {
            "name": "ibmqx_qasm_simulator"
      },
      "status": "COMPLETED",
      "maxCredits": 3,
      "usedCredits": 0,
      "creationDate": "2018-04-05T14:25:37.597Z",
      "deleted": false,
      "id": "d405c5829274d0ee49b190205796df87",
      "userId": "ef072577bd26831c59ddb212467821db",
      "calibration": {}
}, ...]
Listing 3-4

Simplified Response for the Get Jobs API Call

Note

Depending on the size of the execution queue, you may get an empty result ([ ]) if there are no jobs in queue or a formal result as shown in Listing 3-4. Whatever the case make sure the HTTP response code is 200 (OK).

Get Account Credit Information

When an account is created, each user is assigned a number of default execution credits (15) which are spent when running experiments. This call lists your credit information.

Tip

The user id can be obtained from the authentication response via API token or user-password. See the “Authentication” section for details.

Request Parameters

Name

Value

access_token

Your account access token.

HTTP Headers

Name

Value

x-qx-client-application

Defaults to qiskit-api-py

Response Sample

Listing 3-5 shows a sample response for this call.
{
      "institution": "Private Research",
      "status": "Registered",
      "blocked": "None",
      "dpl": {
            "blocked": false,
            "checked": false,
            "wordsFound": {},
            "results": {}
      },
      "credit": {
            "promotional": 0,
            "remaining": 150,
            "promotionalCodesUsed": [],
            "lastRefill": "2018-04-12T14:05:09.136Z",
            "maxUserType": 150
      },
      "additionalData": {
      },
      "creationDate": "2018-04-01T15:36:16.344Z",
      "username": "",
      "email": "",
      "emailVerified": true,
      "id": "",
      "userTypeId": "...",
      "firstName": "...",
      "lastName": "..."
}
Listing 3-5

Credit Information Sample Response

List User’s Experiments

Request Parameters

Name

Value

USER-ID

Your user id obtained from the authentication step.

access_token

Your account access token.

includeExecutions

If true, include executions in the result.

HTTP Headers

Name

Value

x-qx-client-application

Defaults to qiskit-api-py

Response Sample

Listing 3-6 shows a sample response from this call.
{
  "total": 17,
  "count": 17,
  "codes": [{
    "type": "Algorithm",
    "active": true,
    "versionId": 1,
    "idCode": "...",
    "name": "3Q GHZ State YXY-Measurement 1",
    "jsonQASM": {
      ...
    },
    "qasm": "",
    "codeType": "QASM2",
    "creationDate": "2018-04-14T19:09:51.382Z",
    "deleted": false,
    "orderDate": 1523733740504,
    "userDeleted": false,
    "displayUrls": {
      "png": "URL"
    },
    "isPublic": false,
    "id": "...",
    "userId": "..."
  }]}
Listing 3-6

Experiment List Response

Run Experiment

Request Parameters

Name

Value

shots

The number of shots to perform. The higher the number, the better the accuracy of your results will be. Note that this number depletes your credits at a rate of 3 credits per 1024 shots. Space is at a premium in the quantum world.

access_token

Your account access token.

deviceRunType

The device where to run the experiment. This could be

 • A real device name such as ibmqx2 and ibmqx3 for real processors.

 • For simulators: simulator or sim_trivial_2.

seed (optional)

An optional random number required only for simulators.

HTTP Headers

Name

Value

x-qx-client-application

Defaults to qiskit-api-py

Content-Type

application/json

Payload Format

The request body is a JSON document that describes the experiment as shown in the following snippet:
{
  "name": "Experiment NAME",
  "codeType": "QASM2",
  "qasm": "CODE"
}

Response Sample

This is arguably the most important call of the API. As an exercise, let’s take one of the Bell states from the previous section and run it in both the simulator and real device using the REST API.
IBMQASM 2.0;
include "qelib1.inc";
qreg q[2];
creg c[2];
h q[0];
cx q[0],q[1];
h q[0];
s q[1];
h q[1];
t q[1];
h q[1];
measure q[0] -> c[0];
measure q[1] -> c[1];
Listing 3-7

Bell State XW Measurement

Listing 3-7 shows the assembly code from one of the Bell state (XW) experiments performed with the web console in the previous section. Take this code and create a JSON payload of the form: {"name": "NAME", "codeType": "QASM2", "qasm": "ONE-LINE-QASM"}. Note that we must give it an experiment name and the QASM code must be formatted in a single line including line feeds (\n); thus the final payload becomes
{"name": "REST Bell State XW", "codeType": "QASM2", "qasm": "IBMQASM 2.0;\ninclude \"qelib1.inc\";\nqreg q[2];\ncreg c[2];\nh q[0];\ncx q[0],q[1];\nh q[0];\ns q[1];\nh q[1];\nt q[1];\nh q[1];\nmeasure q[0] -> c[0];\nmeasure q[1] -> c[1];"}.

Now we are ready to submit our experiment via REST. Don’t forget that you must authenticate first to obtain an access token.

Tip

REST clients are available for most if not all current browsers. Install your favorite browser REST client, and create an authentication request as described in the “Authentication” section. Save it and keep it handy to obtain your access token.

I will use Chrome’s YARC (Yet Another REST Client) to submit the payload to the simulator first and then to the real device (see Figure 3-8).
../images/469026_1_En_3_Chapter/469026_1_En_3_Fig8_HTML.jpg
Figure 3-8

Chrome’s YARC REST client with payload for Bell state XW experiment

Submit to the Simulator
To submit to the simulator, use the following request parameters:
access_token=ACESS_TOKEN&shots=1&deviceRunType=simulator
Verify that the response code is 200 (OK) and look at the response output. Verify that the experiment has been recorded in the Q Experience console (see Figure 3-9).
../images/469026_1_En_3_Chapter/469026_1_En_3_Fig9_HTML.jpg
Figure 3-9

Web console showing the Bell state XW experiment submitted via REST

Submit to a Real Device
To submit to the real device (ibmqx4 in this case), change the request parameters to
access_token=ACESS_TOKEN &shots=1&deviceRunType=ibmqx4

Note

Real quantum devices may be offline for maintenance or whatever reason. If that is the case, the submission will fail with a 400 (bad request) HTTP response. Make sure the device is online before submitting to a real quantum device!

If all goes well, the job should be put in the execution queue and recorded in the web console. Listing 3-8 shows the result from a submission to a real device with a status of PENDING_IN_QUEUE.
{
  "startDate": "2018-04-16T13:05:43.440Z",
  "modificationDate": 1523883943441,
  "typeCredits": "plan",
  "status": {
    "id": "WORKING_IN_PROGRESS"
  },
  "deviceRunType": "real",
  "ip": {
    "ip": "...",
    "city": "Raleigh",
    "country": "United States",
    "continent": "North America"
  },
  "shots": 1,
  "paramsCustomize": {},
  "deleted": false,
  "userDeleted": false,
  "id": "...",
  "codeId": "...",
  "userId": "...",
  "infoQueue": {
    "status": "PENDING_IN_QUEUE",
    "position": 21,
    "estimatedTimeInQueue": 735
  },
  "code": {
    "type": "Algorithm",
    "active": true,
    "versionId": 1,
    "idCode": "...",
    "name": "REST Bell State XW #1",
    "jsonQASM": {
      ...
      "numberGates": 7,
      "hasMeasures": true,
      "numberColumns": 11,
      "include": "include \"qelib1.inc\";"
    },
    "qasm": "...",
    "codeType": "QASM2",
    "creationDate": "2018-04-16T13:05:42.547Z",
    "deleted": false,
    "orderDate": 1523883943351,
    "userDeleted": false,
    "isPublic": false,
    "id": "...",
    "userId": "..."
  }
}
Listing 3-8

Simplified HTTP Response from the Bell State XW Experiment Submitted via REST

At this point, you have succeeded submitting your first experiment via REST. Try playing by increasing the number of shots of your experiment to achieve greater accuracy.

Run a Job

This call is very similar to the previous Run Experiment; however it features two end points:
  • End point 1: For regular users of the IBM Q Experience.

  • End point 2: For corporate customers. It requires a hub, group, and project ids.

Corporate customers have premium access as well as access to the powerful 20-qubit processors and perhaps the rumored 50-qubit chip coming by the end of 2018.

Request Parameters

Name

Value

access_token

Your account access token

HTTP Headers

Name

Value

x-qx-client-application

Defaults to qiskit-api-py

Content-Type

application/json

Payload Format

The format of the payload embeds all execution parameters: backend name, shots, and code in a single JSON document as shown in the following snippet:
{
  "backend": {
    "name": "simulator"
  },
  "shots": 1,
  "qasms": [{
    "qasm": "qams"
  }, ...]
}

Tip

Experiments submitted through the Run Job end point are not recorded in the Scores section of the Composer but put in an execution queue for processing.

On the other hand, a submission via the Run Experiment end point will record an entry in the Composer. Also, note that any experiment submitted to the simulator will return results immediately. Experiments submitted to a real quantum device will always enter the execution queue in a PENDING state. On completion, a notification email will be sent to the user. Let’s send a quick job to the real device ibmqx4. Paste the following end point into your REST client:

https://quantumexperience.ng.bluemix.net/api/Jobs?access_token=access_token

Set the HTTP Method to POST, access token, and the headers as described in the previous section. Use the following JSON payload:
{
"qasms": [{
 "qasm": "\n\ninclude \"qelib1.inc\";\nqreg q[5];\ncreg c[5];\nu2(-4*pi/3,2*pi) q[0];\nu2(-3*pi/2,2*pi) q[0];\nu3(-pi,0,-pi) q[0];\nu3(-pi,0,-pi/2) q[0];\nu2(pi,-pi/2) q[0];\nu3(-pi,0,-pi/2) q[0];\nmeasure q -> c;\n" }],
 "shots": 1024,
 "backend": {
  "name": "ibmqx4"
 },
 "maxCredits": 3
}
The preceding payload submits a random experiment to the real device ibmqx4. Make sure it is online before submission (or use simulator instead). Also make sure the QASM code is in a single line including line feeds (\n). Note that double quotes must be escaped. If the submission fails, it probably means that the device is offline or your QASM payload is invalid. Double- and triple-check to make sure they are correct. The response I got tells me that my job is RUNNING:
{
  "qasms": [
    {
      "qasm": "...",
      "status": "WORKING_IN_PROGRESS",
      "executionId": "5ba6955fd867ef0046615172"
    }
  ],
  "shots": 1024,
  "backend": {
    "id": "5ae875670f020500393162b3",
    "name": "ibmqx4"
  },
  "status": "RUNNING",
  "maxCredits": 3,
  "usedCredits": 3,
  "creationDate": "2018-09-22T19:17:51.448Z",
  "id": "5ba6955fd867ef0046615171",
  "userId": "5ae875060f0205003931559a",
  "infoQueue": {
    "status": "PENDING_IN_QUEUE",
    "position": 11
  }
}

Note that my job won’t show up in the Composer; however I will get an email with a link to the results.

Get the API Version

It returns the version of the Q Experience REST API.

Request Parameters

Name

Value

access_token

Your account access token

HTTP Headers

Name

Value

x-qx-client-application

Defaults to qiskit-api-py

Response Format

It returns a string with the version of the API, by the time of this writing 6.4.8.

We have peaked inside the Python IBMQuantumExperience REST API to see what goes on behind the scenes. As an exercise let’s build a custom client for Node JS. Here is how.

A Node JS Client for the IBMQuantumExperience

This section presents a simple exercise to mimic one of the components of the Python SDK also known as the QISKit (Quantum Information Software Kit) . In the next chapter, we will dive into the Python SDK in more detail, but we’ll start by saying that the SDK is built on top of two basic libraries:
  • IBMQuantumExperience : This is a REST client implementation in Python which I peeked into to present the REST API from the previous section. This library is not well documented. It makes sense as it is meant to be a modularized library that may change in the future.

  • QISKit SDK : This is the main entry point to all your quantum programs. It packs gate logic; assembly translation; simulators, a local python simulator and a fast C++ simulator; and much more. This library also invokes IBMQuantumExperience for all interactions via REST to the IBM Q Experience platform.

Python is a great language, but Node JS is all the craze right now in the data center; thus this section presents a simple implementation of the REST API for Node JS. Here are some reasons why this would be a useful library:
  • Node JS is a powerhouse for network I/O asynchronous calls. It is fast, and it is the perfect platform for REST clients.

  • Python is a good language, with a plethora of amazing numerical, math, chart libraries, but has some idiosyncrasies that some may find unattractive. For example, indentation is relevant in Python (you cannot mix TABS and spaces – there are no braces to differentiate blocks). This drove me crazy at the beginning and took me a while to figure out as almost all computer languages use braces to differentiate logic blocks. No such thing in Python, you must use spaces or TABS and you cannot mix them. I don’t like this. I think it is bad design because if you make a mistake, you don’t know where a logic block ends. That’s what braces are for.

  • Variety is always good: after all my troubles with Python, I thought this library could be the foundation for a QISKit clone for Node JS.

So let’s get started.

Build a Node Module for IBMQuantumExperience

I have tried to keep names as close as possible to the Python version. To create a Node JS module, create a folder named IBMQuantumExperience, and initialize Node JS as shown in the following set of commands:
$ mkdir IBMQuantumExperience
$ cd IBMQuantumExperience
$ npm init

Tip

Linux users: I have used Windows to write this section; furthermore I assume that you have installed Node JS, are familiar with Node modules, and can code in Javascript. All in all, you can get Node installers for all platforms at https://nodejs.org/en/ . Also note that Linux complains about uppercase names for package names. Save yourself a headache and use Windows to go thru this section.

Node provides a package manager called npm (which is pretty much the same thing as Python’s pip) which can be used to initialize your module. The third command will create two files in the current folder:
  • index.js: This is your module code. Note for Linux users, this file may not be created. If so create it manually.

  • Package.json: This is the module descriptor with information such as name, version, author, dependencies, and more.

Create a folder test in the same location to contain unit tests and install the powerful Node rest client request:
$mkdir test
$ npm install request

The second command installs the popular HTTP request package and all its dependencies in the current folder. Now we are ready to start implementing the REST API from the previous section. Open index.js in your favorite editor and let’s get started.

Export API Methods

To expose an API via Node, use the module.exports library as shown in Listing 3-9. Note that this is a partial implementation of the library, as the pieces are assembled throughout the following sections. Nevertheless, a full implementation is available from the book source under Workspace\Ch03\IBMQuantumExperience. That being said, you should be able to paste all these listings into index.js. Again, I am assuming here that you are familiar on how modules are written in Node JS.
const log = require('./log'); // A simple custom log library (see the debug section)
const request = require('request');
//...
module.exports =  {
  init: function (cfg) {
    _config = cfg;
    var debug = _config.debug ? _config.debug : false;
    log.init (debug);
    return loginWithToken ();
  },
  getCalibration  : calibration,
  getBackends    : backends,
  getParameters  : parameters,
  runExperiment  : experiment
  // Left as exercise  getJobs      : jobs,
  // Left as exercise  getMyCredits  : credits
}
Listing 3-9

Expose Public API Methods via Node

In Listing 3-9 we import an external library using the require keyword:
  • Line 2 imports the request HTTP client library to interact with Q Experience.

  • Line 5 declares the public methods to be exposed by this module:
    • init: This method authenticates against the Q Experience platform as described in the previous section “Remote Access via the REST API.”

    • getCalibration: It returns the platform’s calibration parameters for a given device.

    • getBackends: It returns a list of quantum devices (and simulators) available for use.

    • getParameters: It returns the device parameters as described under the Devices section of the Composer web console.

    • runExperiment: It runs an experiment remotely in the simulator or real quantum device.

    • getJobs: It returns a list of current jobs in the experiment execution queue.

    • getMyCredits: It returns the user’s execution credit and other useful information.

Authenticate with a Token

Before authentication, the library is initialized the same way as in Python, with a configuration JSON object containing the Platform URL, API token, and more. For example, this is how we would test the get backend information REST API call (taken from test.js):
// require the `index.js` file from the same directory.
const qx = require('index.js');
// Put your API token here
var config = { APItoken: 'YOUR_API_TOKEN'
  , debug    : true
  , 'url'    : 'https://quantumexperience.ng.bluemix.net/api'
  , 'hub'    : 'MY_HUB'
  , 'group'  : 'MY_GROUP'
  , 'project'  : 'MY_PROJECT'
}
// Get backend information
async function testBackends() {
  await qx.init(config);
  var result = await qx.getBackends();
  console.log("---- BACKENDS ----\n" + JSON.stringify(result) + "\n-----" );
}
Remember that hub, group, and project are parameters for corporate customers only; thus they are not used in this implementation; however support for them can be easily added. Once initialized, simply submit a POST request to log in with a token as described by the REST API (see Listing 3-10). Note that this code, as well as all the listings throughout these sections, goes in index.js.
function loginWithToken () {
  let options = {
    url: _config.url + '/users/loginWithToken',
    form: {'apiToken': _config.APItoken}
  };
   return new Promise(function(resolve, reject) {
    // Do async job
    // {"id":"Access tok","ttl":1209600,"created":"2018-04-17T23:30:21.089Z","userId":"userid"}
    request.post(options, function(err, res, body) {
      if (err) {
        reject(err);
      }
      else {
        var json     = JSON.parse(body);
        _accessToken  = json.id;
        _userId      = json.userId;
        log.debug("Got User:" + _userId + " Tok:" +  _accessToken);
        resolve(JSON.parse(body));
      }
    });
  })
}
Listing 3-10

Token Authentication via REST

In Listing 3-10
  • The request.post system call is used to send an HTTP POST to the end point https://quantumexperience.ng.bluemix.net/api/users/loginWithToken using the JSON payload {'apiToken': 'YOUR_TOKEN'}. As described by the REST API, this call returns a new JSON document: {"id":"TOKEN","ttl":1209600,"created":"DATE","userId":"USERID"}. This document is parsed and the access token (id) and user id (userId) saved for later use.

  • Note that because all network I/O in Node is asynchronous, all methods return a Promise. This is basically an asynchronous task that encapsulates the difficulty of having to wait for the task to complete before reading results. Thus if the HTTP request call succeeds, the resolve callback from the Promise will fire with the HTTP response data; else the Promise reject callback will be invoked.

Tip

Promises are a compelling alternative to callbacks for asynchronous code. Nevertheless they can be confusing some times. All in all, Promises are becoming the de facto standard for asynchronous programming in Javascript.

Nevertheless if you find the Promise handling code convoluted, there is an even easier way to deal with this, and it is shown in the next section where we implement a method to fetch the list of backends.

List Backends

Listing 3-11 shows a Node request to fetch backends from Q Experience.
const _defaultHdrs = {
      'x-qx-client-application': _userAgent
};
function backends () {
  let options = {
    url: _config.url + '/Backends?access_token=' + _accessToken,
    headers: _defaultHdrs
  };
  return new Promise(function(resolve, reject) {
    // Do async job
    request.get(options, function(err, res, body) {
      if (err) {
        reject(err);
      }
      else {
        resolve(JSON.parse(body));
      }
    });
  })
}
Listing 3-11

Get Backend List via Node

To test the preceding method, we can use the async/await feature from Node.js >=7.6 as shown in the following snippet:
async function testBackends() {
  await qx.init(config);
  var result = await qx.getBackends();
  console.log("---- BACKENDS ----\n" + JSON.stringify(result) + "\n-----" );
}

Tip

An async function can contain an await expression that pauses the execution of the async function and waits for the passed Promise’s resolution and then resumes the async function’s execution and returns the resolved value.

List Calibration Parameters

Listing 3-12 shows how to get calibration and hardware parameters for a specific backend in IBM Q Experience:
function calibration (name) {
  let options = {
    url: _config.url + '/Backends/' + name +'/calibration?access_token=' + _accessToken,
    headers: _defaultHdrs
  };
  return new Promise(function(resolve, reject) {
    request.get(options, function(err, res, body) {
      if (err) {
        reject(err);
      }
      else {
        resolve(JSON.parse(body));
      }
    });
  })
}
function parameters (name) {
  let options = {
    url: _config.url + '/Backends/' + name +'/parameters?access_token=' + _accessToken,
    headers: _defaultHdrs
  };
  return new Promise(function(resolve, reject) {
    request.get(options, function(err, res, body) {
      if (err) {
        reject(err);
      }
      else {
        resolve(JSON.parse(body));
      }
    });
  })
}
Listing 3-12

Get Device Calibration and Parameter Data

To test the code, create an async function and use the await keyword to get the response from the asynchronous task as shown in the following snippet:
async function testCalibration() {
  await qx.init(config);
  var result1 = await qx.getCalibration('ibmqx4');
  var result2 = await qx.getParameters('ibmqx4');
  console.log(JSON.stringify(result1) );
  console.log(JSON.stringify(result1) );
}

For the final step, let’s see how an experiment can be run.

Run the Experiment

This is the most important call of the API, and once executed, the experiment should be recorded under the scores section of your IBM Q Experience web console (see Listing 3-13). To submit an experiment programmatically, send an HTTP POST to the /codes/execute end point with the JSON payload:
{'name': name, "codeType": "QASM2", "qasm":  "YOUR_QASM_CODE"}
  • Remember that the assembly code must be formatted in a single line with line feeds (\n) to separate instructions. For example, the following code declares 5 qubits and 5 classical registers: "\n\ninclude \"qelib1.inc\";\nqreg q[5];\ncreg c[5];\n".

  • The name parameter defines the experiment name to be recorded in the web console.

  • The shots parameter is the number of shots executed by the quantum processor.

  • The device parameter can be simulator (for the remote simulator) or a real quantum device name such as ibmqx4.

Tip

If you run an experiment in a real device, it will enter an execution queue for future processing. You will receive an email on completion. On the other hand, if you run the experiment in the remote simulator, the results will be returned synchronously.

const _userAgent = 'qiskit-api-py'; // A global
function experiment (name, qasm, shots, device) {
  let options = {
    url: _config.url + '/codes/execute?access_token=' + _accessToken
       + '&shots=' + shots + '&deviceRunType=' + device,
    headers: {'Content-Type': 'application/json', 'x-qx-client-application': _userAgent} ,
    form: {'name': name, "codeType": "QASM2", "qasm": qasm}
  };
  return new Promise(function(resolve, reject) {
    request.post(options, function(err, res, body) {
      if (err) {
        reject(err);
      }
      else {
        resolve(JSON.parse(body));
      }
    });
  })
}
Listing 3-13

Run an Experiment

Paste Listing 3-13 into index.js, use the following snippet to run an experiment in the real quantum device ibmqx4, then verify the experiment has been recorded in the web console, and finally wait for a notification email.
async function testExperiment () {
  await qx.init(config);
  var name   = "REST Experiment from Node JS #1"
  var qasm   =  "\n\ninclude \"qelib1.inc\";\nqreg q[5];\ncreg c[5];\nu2(-4*pi/3,2*pi) q[0];\nu2(-3*pi/2,2*pi) q[0];\nu3(-pi,0,-pi) q[0];\nu3(-pi,0,-pi/2) q[0];\nu2(pi,-pi/2) q[0];\nu3(-pi,0,-pi/2) q[0];\nmeasure q -> c;\n";
  var shots   = 1;
  var device   = "ibmqx4";
  var result   = await qx.runExperiment(name, qasm, shots, device);
  console.log("---- EXPERIMENT " + name + " ----\n" + JSON.stringify(result) + "\n-----" )
}

Tip

The code for the IBMQuantumExperience Node module is included in the book source under Workspace\Ch03\IBMQuantumExperience. The project has a test script under test/tests.js. Edit this file, add your API token, and execute it from IBMQuantumExperience with the command: node test/tests.js.

Debugging and Testing

For simple debugging I have created the submodule log.js (at the same level as index.js) and used the quintessential console object to display information into the console as shown in the following snippet:
var _debug = false;
function LOGD( tag, txt ) {
  if ( _debug ) {
    console.log('[DBG-QX] ' + tag + ' '  + (txt ? txt : "));
  }
}
function LOGE( tag, txt ) {
  console.error('[ERR-QX] ' + tag + ' ' + (txt ? txt : "));
}
function init (debug) {
  _debug = debug;
}
exports.init = init;
exports.debug = LOGD;
exports.error = LOGE;
The main module (index.js) uses this submodule to display debug messages in the console. Finally, to test the package, edit test/tests.js and paste the test snippets described throughout these sections as shown in the following partial listing from tests.js:
// test/tests.js require the `index.js` file from the same directory.
const qx = require('../');
// Put your API token here
var config = { APItoken: 'API-TOKEN'
  , debug: true
  , 'url': 'https://quantumexperience.ng.bluemix.net/api'
  , 'hub': 'MY_HUB'
  , 'group': 'MY_GROUP'
  , 'project': 'MY_PROJECT'
};
async function testBackends() {
 await qx.init(config);
 var result = await qx.getBackends();
 console.log("---- BACKENDS ----\n" + JSON.stringify(result) + "\n-----" );
}
async function testJobs () {
 await qx.init(config);
 var filter = '{"limit":2}';
 var jobs = await qx.getJobs(filter);
 console.log ("---- JOBS----\n" + JSON.stringify(jobs) + "\n----");
}
// Paste all test snippets here...
// ....
try {
 testBackends();
 testJobs ();
 // more tests here...
}
catch (e){
 console.error(e);
}

To run the test, execute node test\tests.js within the IBMQuantumExperience folder. Note that I have left out two methods: getJobs and getMycredits as an exercise. With this foundation, you should be able to easily implement and test them.

Share with the World: Publish Your Module

If you wish to share your work with the world, you can publish your module to the npm registry. For this you must create a user account at www.npmjs.com/ or manually using the commands
npm adduser
npm publish
Make sure you document your code by adding a markdown document (readme.md) to the root folder. After publishing, navigate to https://​npmjs.​com/​package/​<package> and check out your live module. Now others should be able to install it with
npm install IBMQuantumExperience
Node JS developers can now submit experiments to the Q Experience with code like this:
const qx = require('IBMQuantumExperience');
...
async function sendExperiment () {
  var config = { APItoken: 'API-TOKEN'
   , 'url': 'https://quantumexperience.ng.bluemix.net/api', 'debug': false};
  await qx.init(config);
  var name   = "REST Experiment from Node JS #1"
  var qasm   =  "MY_QASM";
  var device   = "ibmqx4";
  var result   = await qx.runExperiment(name, qasm, 1024, device);
}

In this chapter you have taken the first step in your new career as a quantum programmer. IBM has created an amazing cloud platform to learn about these incredible machines. We should thank the good folks at IBM for making this platform freely accessible to the masses. For now, quantum computers are experimental machines, so don’t expect to get one at the local hardware store. Nevertheless soon they will take over the data center, so now is the time to learn how to program them.