Книга: Разработка с использованием квантовых компьютеров
Назад: 3. IBM Q Experience: уникальная платформа для квантовых вычислений в облаке
Дальше: 5. Запускаем движки: от квантовой генерации случайных чисел до телепортации с остановкой на сверхплотном кодировании

4. QISKit — отличный SDK для квантового программирования на Python

В этой главе вы познакомитесь с QISKit — лучшим SDK для квантового программирования. Вы узнаете, как просто установить SDK в своей локальной системе. Но прежде, чем писать первую квантовую программу, всегда полезно понять, что такое квантовые вычисления и чем они отличаются от классических. Для этой цели приведено очень простое объяснение состояний кубитов и квантовых вентилей с использованием линейной алгебры. В этой главе также показано, как квантовые вычисления могут в точности повторить классический аналог и, кроме того, ускорить получение результатов. Далее в главе рассматривается строение квантовой программы, включая системные вызовы, форматы составления схем, квантовый ассемблер и многое другое.

QISKit содержит набор полезных моделирующих устройств для локального или удаленного выполнения ваших программ, он также позволяет работать в режиме реального времени. Шаг за шагом вы узнаете, как запускать квантовые программы на реальном устройстве, предоставленном потрясающей облачной платформой IBM Q Experience. Итак, перейдите на свой Рабочий стол, и приступим.

Установка QISKit

QISKit — это Quantum Information Software Kit, SDK для квантового программирования в облаке. Он написан на Python — мощном сценарном языке для решения научных задач. Мой опыт в основном связан с бизнесом, и я мало писал на Python в последнее время, поэтому давайте рассмотрим установку SDK как в Linux CentOS 6 или 7, так и в Windows 64. Начнем с самого простого (Windows), а затем перейдем к самому сложному (CentOS).

Настройка в Windows

QISKit требует Python 3.5 или более поздней версии. Если у вас Windows, то, скорее всего, Python не установлен. Если это так, вы можете получить установщики с веб-сайта Python.org. Загрузите установщик, запустите его и проверьте, произошла ли установка, выполнив в командном окне следующую команду:

C:\>Python -V

Python 2.7.6

У меня старый добрый Python 2.7, а у вас может быть установлено несколько версий Python одновременно. Я скачал встраиваемый ZIP-файл и развернул его в C:\Python36-64, так что в моем случае:

C:\>C:\Python36-64\Python.exe -V

Python 3.6.4

В Python есть замечательный менеджер пакетов pip (preferred installer program), который сильно упрощает установку модулей. Таким образом, чтобы установить QISKit, просто наберите в консоли:

C:\>pip install qiskit

Вывод на экран должен выглядеть аналогично коду из листинга 4.1. Убедитесь, что не было сообщений об ошибках.

Листинг 4.1. Установка QISKit в Windows 64 бит

Collecting qiskit

    Using cached qiskit-0.4.11.tar.gz

Collecting IBMQuantumExperience>=1.8.28 (from qiskit)

    Using cached IBMQuantumExperience-1.9.0-py3-none-any.whl

Collecting matplotlib<2.2,>=2.1 (from qiskit)

    Using cached matplotlib-2.1.2.tar.gz

Collecting networkx<2.1,>=2.0 (from qiskit)

    Downloading networkx-2.0.zip (1.5MB)

        100% |████████████████████| 1.6MB 400kB/s

 

145

Collecting numpy<1.15,>=1.13 (from qiskit)

    Downloading numpy-1.14.2-cp36-cp36m-manylinux1_i686.whl (8.7MB)

        100% |████████████████████| 8.7MB 105kB/s

    Running setup.py install for pycparser … done

    Running setup.py install for matplotlib … done

    Running setup.py install for networkx … done

    Running setup.py install for ply … done

    Running setup.py install for mpmath … done

    Running setup.py install for sympy … done

    Running setup.py install for qiskit … done

Successfully installed IBMQuantumExperience-1.9.0 qiskit-0.4.11

requests-2.18.4 …

Вот и все. Вы сделали первый шаг в путешествии в качестве квантового программиста. Для пользователей Linux настроим все в CentOS 6 или 7.

Настройка в Linux CentOS

В CentOS 6 или 7 настройка немного сложнее. Это связано с тем, что CentOS фокусируется в основном на стабильности, а не на ультрасовременном программном обеспечении. Таким образом, CentOS поставляется со встроенным Python 2.7. Более того, официальный дистрибутив не предоставляет пакетов для Python 3.5. Однако это не означает, что Python 3.5 нельзя установить. Посмотрим, как это делается.

Примечание

Инструкции, приведенные в этом разделе, должны работать для любых вариантов Linux, основанных на базе Red Hat, таких как RHEL 6–7, CentOS 6–7 и Fedora Core.

Шаг 1. Подготовка системы

Прежде всего убедитесь, что yum (менеджер обновлений Linux) актуален, выполнив команду:

$ sudo yum -y update

Затем установите yum-utils — коллекцию утилит и плагинов, расширя­ющих и дополняющих yum:

$ sudo yum -y install yum-utils

Установите инструменты разработки CentOS. К ним относятся компиляторы и библиотеки, позволяющие создавать и компилировать многие типы программного обеспечения:

$ sudo yum -y groupinstall development

Теперь установим Python 3. Обратите внимание, что мы будем запускать несколько версий Python: официальную, 2.7 и 3.6 для разработки.

Шаг 2. Установка Python 3

Чтобы выйти за пределы ограничений поставляемого по умолчанию дистрибутива CentOS, можно воспользоваться проектом, созданным на общественных началах, под названием Inline with Upstream Stable (IUS). Это набор новейших библиотек для тех ОС, которые их не предоставляют, таких как CentOS. Давайте установим в ней IUS через yum:

$ sudo yum -y install https://centos7.iuscommunity.org/ius-release.rpm

(CentOS7)

$ sudo yum -y install https://centos6.iuscommunity.org/ius-release.rpm

(CentOS6)

После завершения установки IUS мы можем установить последнюю версию Python (3.6):

$ sudo yum -y install python36u

Проверьте, чтобы убедиться, что установка выполнена корректно:

$ python3.6 -V

Python 3.6.4

Теперь установим и проверим pip:

$ sudo yum -y install python36u-pip

$ pip3.6 -V

Наконец, нам нужно установить пакет python36u-devel из IUS, который предоставляет полезные библиотеки для разработки:

$ sudo yum -y install python36u-devel

Шаг 3. Создание виртуальной среды

Этот шаг может быть полезен только в том случае, если у вас многопользовательская система с несколькими версиями Python и вы не хотите мешать другим пользователям. Например, чтобы создать виртуальную среду в своей домашней папке, выполните:

$ mkdir $HOME/qiskit

$ cd $HOME/qiskit

$ python3.6 -m venv qiskit

С помощью этой последовательности команд в домашней папке пользователя создается папка с названием qiskit, где будут храниться все ваши квантовые программы. В ней создается также виртуальная среда Python 3.6, названная qiskit. Чтобы активировать среду, выполните команду:

$ source qiskit/bin/activate

(qiskit) [centos@localhost qiskit]$

В виртуальной среде вы можете использовать команду python вместо python3.6 и pip вместо pip3.6, если вам так нравится:

$ python -V

Python 3.6.4

Совет

Если вы не активируете виртуальную среду, то используйте python3.6 и pip3.6 вместо python и pip.

Шаг 4. Установка QISKit

Активируйте свою виртуальную среду и установите QISKit с помощью команды:

$ pip install qiskit

В листинге 4.2 показан стандартный вывод для предыдущей команды.

Листинг 4.2. Установка QISKit в CentOS 6

Collecting qiskit

    Downloading qiskit-0.5.7.tar.gz (4.5MB)

        100% |████████████████████| 4.5MB 183kB/s

Collecting IBMQuantumExperience>=1.8.28 (from qiskit)

    Downloading IBMQuantumExperience-1.9.0-py3-none-any.whl

Collecting matplotlib<2.2,>=2.1 (from qiskit)

    Downloading matplotlib-2.1.2.tar.gz (36.2MB)

        100% |████████████████████| 36.2MB 18kB/s

        Complete output from command python setup.py egg_info:

        ====================================

        Edit setup.cfg to change the build options

        BUILDING MATPLOTLIB

            matplotlib: yes [2.1.2]

            python: yes [3.6.4 (default, Dec 19 2017, 14:48:15) [GCC

                4.4.7 20120313 (Red Hat 4.4.7-18)]]

            platform: yes [linux]

Installing collected packages: IBMQuantumExperience, numpy, python-dateutil, pytz, cycler, pyparsing, matplotlib, decorator, networkx, ply, scipy, mpmath, sympy, pillow, qiskit

    Running setup.py install for pycparser … done

    Running setup.py install for matplotlib … done

    Running setup.py install for networkx … done

    Running setup.py install for ply … done

    Running setup.py install for mpmath … done

    Running setup.py install for sympy … done

    Running setup.py install for qiskit … done

Successfully installed IBMQuantumExperience-1.9.0 qiskit-0.4.11 requests-2.18.4 requests-ntlm-1.1.0 scipy-1.0.1 six-1.11.0 sympy-1.1.1 urllib3-1.22

 

(qiskit) [centos@localhost qiskit]$

Совет

В виртуальной среде пакеты Python будут устанавливаться в домашнюю папку среды lib/python3.6/site-packages вместо системного пути, как показано на рис. 4.1.

04_01.tif 

Рис. 4.1. Расположение папки виртуальной среды Python virtual

Теперь мы готовы начать писать квантовый код. Посмотрим, как это делается.

Кубит 101: базовая алгебра

Прежде чем приступить к написанию квантовых программ, нужно немного освежить знания в области фундаментальной математики, чтобы понимать, что происходит за кулисами. В главе 2 вы узнали, как кубит представляется сферой Блоха (см. рис. 2.7): это геометрическое представление чистого состояния двухуровневой квантово-механической системы (кубита). Но, возможно, лучший способ понять основную модель кубита и влияние квантовых вентилей — воспользоваться его алгебраическим представлением. Для этого вам нужно вспомнить некоторые базовые понятия линейной алгебры, включая следующие.

Линейные векторы. Простые векторы вида 31771.png, которые будут использоваться для представления базовых состояний кубита.

Комплексные числа. Комплексным называется число, состоящее из вещественной и мнимой частей, представляемое как a + bi, где 31781.png. Обратите внимание на то, что комплексные числа не могут существовать в нашей физической реальности. Коэффициенты α, β состояния суперпозиции кубита 31790.png являются комплексными числами.

• Комплексное сопряжение. Термин, который вы часто будете слышать в связи с квантовыми вентилями. Чтобы получить комплексное сопряжение, просто поменяйте на противоположный знак при мнимой части: a + bi становится abi и наоборот.

• Произведение матриц. Если A является матрицей размерности n×m, а B — матрицей размерности m×p, то их произведение AB — это матрица размерности n×p, где m элементов строки матрицы A умножаются на m элементов столбца матрицы B, а произведения суммируются для получения элемента матрицы AB. Возьмите первую строку первой матрицы и умножьте каждый ее элемент на каждый элемент первого столбца второй матрицы, затем суммируйте произведения, чтобы получить первый элемент матрицы результатов (рис. 4.2). Не стоит паниковать, большинство матриц, которые мы рассмотрим, имеют размерность 2 × 2, а их элементами являются 0 и 1.

30021.png 

Рис. 4.2. Базовая операция матричного произведения

Алгебраическое представление квантового бита

В классической модели основной единицей информации является бит, который представлен 0 или 1. На физическом уровне бит преобразуется в поток напряжения через транзистор. В квантовых вычислениях основной единицей является квантовый бит (кубит), который физически переводится в манипуляции с фотонами, электронами или атомами. Алгебраически кубит представлен кет-вектором.

Примечание

Обозначение «кет-вектор» было введено в 1939 году физиком Полом Дираком и известно также как нотация Дирака. Кет-вектор обычно представлен в виде вектора-столбца и обозначается 31801.png.

Скобочная нотация Дирака

В нотации Дирака базовые квантовые состояния кубита представлены векторами 31809.png и 31819.png. Они называются вычислительными базисными состояниями.

Примечание

Квантовое состояние кубита представляет собой вектор в двумерном комплексном векторном пространстве. Проиллюстрируем это на примере простого графа.

На рис. 4.3 показано комплексное векторное пространство, используемое для представления состояния кубита. Слева изображено так называемое базисное состояние из двух единичных векторов для состояний 31831.png и 31841.png в нотации Дирака. Справа показано общее квантовое состояние, представляющее собой линейную комбинацию двух этих состояний. Таким образом, базисные состояния и общие квантовые состояния могут быть записаны как векторы:

31853.png;

31862.png,

где α и β — амплитуды единичного вектора. Обратите внимание, что амплитуда единичного вектора должна быть равна 1, в связи с чем α и β должны подчиняться ограничению |α|2 + |β|2 = 1. Это алгебраическое представление является ключом к пониманию воздействия логического вентиля на кубит, как вы увидите позже.

30039.png 

Рис. 4.3. Квантовые состояния кубита

Так почему же состояние кубита представлено как вектор в более сложном представлении, чем его классический аналог? Зачем вообще использовать векторы? Причина в следующем: это позволяет построить лучшую модель вычислений, что будет видно, когда мы станем рассматривать квантовые вентили и суперпозицию состояний. В общем, квантовая механика — это теория, развивавшаяся на протяжении многих десятилетий, и, в конце концов, вектор — очень простой математический объект, который легко понять и которым просто манипулировать. Возможно, это лучший рабочий инструмент.

Суперпозиция — это просто красивое слово

Суперпозиция определяется физиками как свойство элементарных частиц находиться в нескольких состояниях одновременно. Если вам трудно понять эту концепцию, на помощь придет линейная алгебра.

Примечание

Суперпозиция — это просто линейная комбинация состояний 31870.png и 31880.png, то есть 31890.png, где длина вектора состояния равна 1, как показано на рис. 4.3.

Скобочная нотация кажется слишком странной? Используйте векторы

Если вам нравится алгебра и вы считаете, что скобочная нотация сбивает вас с толку, просто возьмите вместо нее знакомое векторное представление. Таким образом, суперпозиция из предыдущего раздела может быть записана как:

31899.png .

Обратите внимание, что кет-векторы подчиняются тем же правилам, что и векторы. Например, для них справедливо умножение на скалярную величину:

31908.png .

Изменение состояния кубита с помощью квантовых вентилей

Цель квантовых вентилей — управление состоянием кубита для достижения желаемого результата. Они являются основными строительными блоками квантовых вычислений так же, как классические логические элементы в классическом мире. Некоторые квантовые вентили являются эквивалентом классических аналогов. Рассмотрим их.

Вентиль НЕ (Паули X)

Самый простой вентиль, воздействующий на один кубит. Это квантовый эквивалент классического элемента НЕ, как и его аналог, он изменяет состояние кубита на противоположное, то есть:

31917.png.

На суперпозицию вентиль X действует линейно, то есть он изменяет соответствующее состояние. Таким образом, 31927.png становится 31939.png, а 31948.png становится 31956.png:

31966.png.

На квантовых схемах вентиль НЕ изображается как X, он известен также как вентиль Паули X (назван в честь австрийского физика Вольфганга Паули, одного из основателей квантовой механики).

30047.png 

Начиная с базисного состояния 31974.png для 0-го кубита, данное состояние распространяется по цепи, пока к нему не будет применено управляющее воздействие, а затем результат продолжит распространяться.

Существует другой способ увидеть вентиль Х в действии — с помощью его матричного представления. Можно в точности увидеть, как состояние меняется на противоположное, используя матрицу Паули:

31991.png.

Состояние кубита меняется на противоположное с помощью матричного представления вентиля Х и векторов 32002.png и 32011.png:

32020.png;

32028.png.

Существует еще более простая квантовая схема, самая простая из всех — квантовая проволока, обозначаемая греческой буквой «пси» 32040.png, которая описывает вычислительное состояние во времени. Оно может показаться элементарным, но физически реализовать его сложнее всего. Из-за атомарного масштаба квантовая проволока (представьте себе фотоны, электроны или отдельные атомы) очень хрупка и подвержена ошибкам, обусловленным окружающей средой.

Другим интересным свойством вентиля X является то, что два элемента НЕ в строке дают единичную матрицу (I) — очень важный инструмент в линейных преобразованиях. Давайте выполним расчеты.

30056.png 

32052.png 

Чтобы понять, каково влияние схемы, посмотрим, что произойдет, когда мы перемножим две матрицы X:

32068.png.

Вентиль X — это простейший пример квантового логического элемента, схемы и вычислений.

В следующем разделе рассмотрим истинно квантовый вентиль Адамара и то, как он может переключать суперпозиции с помощью схем и алгебры.

Истинно квантовые вычисления: управление суперпозициями с помощью вентиля Адамара

Воздействие вентиля Адамара на базисные состояния формально определяется как:

32076.png .

Кроме того, суперпозиции состояний 32085.png вентиль Адамара сопоставляет:

32093.png .

В схеме и матричном представлении фильтр Адамара воздействует на одиночный кубит.

30063.png 

32103.png 

Применяя вентиль H к базисным состояниям 32113.png и 32128.png, получим:

32137.png;

 

32145.png .

Так исходя из каких вычислительных соображений используется вентиль Адамара? Что он дает нам?

Если не вдаваться в технические детали, ответ заключается в том, что вентиль Адамара расширяет диапазон состояний, возможных для квантовой схемы. Это важно, потому что расширение состояний позволяет находить быстрые способы решения и, следовательно, ускорять вычисления. Можно провести аналогию с игрой в шахматы. Например, если бы вашему слону было позволено двигаться, как ферзю и слону одновременно (расширение состояний), это дало бы вам преимущество в игре и позволило быстрее поставить мат сопернику. Увеличение мощности квантовой машины — вот что дает вентиль Адамара.

Измерение квантового состояния сложнее, чем кажется

Представьте, что в подвале вашего дома есть лаборатория. Вам даны кубит в состоянии 32159.png и измерительный прибор, и вас просят вычислить коэффициенты α и β. То есть вычислить квантовое состояние. Задача может показаться простой, однако это невозможно сделать. Принципы квантовой механики утверждают, что квантовое состояние системы непосредственно не наблюдается. Лучшее, что можно сделать, — угадать приблизительную информацию об α и β. Этот процесс называется измерением в вычислительном базисе.

30073.png 

Результатом измерения квантового состояния 32171.png являются классические биты:

32180.png с вероятностью |α|2;

32188.png с вероятностью |β|2.

Таким образом, процесс измерения определяет вероятности для классических битов 0 и 1 равными абсолютным значениям коэффициентов α и β, возведенным в квадрат. Представить на физическом уровне, как протекает этот процесс, можно наблюдением физического фотона, атома или электрона с помощью измерительного устройства. Поэтому при измерениях часто используются квантовые вентили.

Измерение нарушает состояние квантовой системы, давая в результате классические биты. Важно помнить, что по завершении этого процесса коэффициенты α и β разрушаются. Это означает, что мы не можем хранить большие объемы информации в кубите. Представьте: если бы мы могли измерить точные значения α и β, то с помощью комплексных чисел теоретически можно было бы хранить бесконечное количество классической информации в состоянии кубита. Вычисляя точные значения α и β, мы могли бы извлечь всю эту информацию. Однако это невозможно. С точки зрения квантовой механики это недопустимо.

Последнее замечание по поводу измерений касается нормализации квантового состояния: при измерении в вычислительном базисе 32197.png сумма вероятностей для классических битов 0 и 1 должна быть равна 1. То есть:

Вероятность(0) + Вероятность(1) = |α|2 + |β|2 = 1.

Значит, длина вектора квантового состояния должна быть равна 1 (нормирована). Это происходит из-за того, что вероятности для измерения в сумме дают 1. В следующем разделе мы поговорим о том, как обобщаются однокубитные логические вентили, что они собой представляют и как используются для построения более сложных схем.

Обобщенные однокубитные вентили

До сих пор мы видели два простых вентиля X и H, представленных матрицами:

32205.png .

Вспомните также, что суперпозиция квантового состояния выражается как вектор 32216.png. Тогда применение обоих вентилей к квантовому состоянию может быть представлено в обобщенном виде для любой единичной матрицы:

32232.png, где U = H, X.

U называется обобщенным однобитовым вентилем с тем ограничением, что U должен быть унарным.

Примечание

Матрица U является унитарной, если результатом ее умножения на эрмитово сопряженную U является единичная матрица: UU = I. Эрмитово сопряжение (https://en.wikipedia.org/wiki/Hermitian_con­jugate) обозначается символом † (https://en.wikipedia.org/wiki/Dagger): U = (UT)*, то есть комплексное сопряжение транспонированной матрицы.

Транспонированная матрица — это новая матрица, строки которой являются столбцами первоначальной. Например, если 32241.png, то 32255.png. Затем для получения эрмитова сопряжения 32263.png возьмите комплексное сопряжение каждого элемента. (Комплексным сопряжением a + bi, где a и b вещественные, является abi, то есть меняется на противоположный знак при мнимой части, если таковая имеется.)

Обратите внимание, что оба вентиля, H и X, должны быть унарными. Это очень просто проверить, вычислив XX = I и HH = I:

32273.png;

32285.png.

Унитарные матрицы хороши для квантовых вентилей

Вопрос, который возникает после прочтения предыдущего раздела: зачем нужны все эти трудности? Почему вентили X и H должны быть унарными? Ответ заключается в том, что унитарные матрицы сохраняют длину вектора. Это полезно для квантовых вентилей, потому что они требуют нормализации входных и выходных состояний (имеют длину вектора 1). На самом деле унитарные матрицы — это единственный тип матриц, сохраняющих длину, и, следовательно, единственный тип матриц, который можно использовать для квантовых вентилей. В общем, возникают более глубокие вопросы: почему квантовые вентили должны быть в первую очередь линейными и зачем вообще применять матричное представление? Мы постараемся ответить на них в следующем разделе, а пока нужно принять это как данность.

Другие однокубитные вентили

В предыдущем разделе мы рассмотрели однокубитные вентили X и H. В то же время существуют и другие однобитные вентили, которые полезны в квантовых вычислениях.

У вентиля X есть два партнера: Y и Z. Они образуют трио, известное как вентили Паули (σ):

30082.png 

32298.png 

Эти три матрицы подходят для задач обработки информации, таких как сверхплотное кодирование (SDC) — процесс, который ориентирован на эффективное хранение классической информации в кубите. Они также используются при анализе свойств атома, таких как спин электрона. Вдобавок тесно связаны с тремя измерениями пространства XYZ.

Вентиль вращения:

30089.png 

32306.png 

Представляет собой уже знакомый нам поворот на угол θ в реальном пространстве. Это унитарная матрица, и в данном случае вентиль Т выполняет вращение на π/4 вокруг оси Z. Этот вентиль требуется для универсального контроля.

Вентили также могут управлять многими кубитами, как мы увидим в следующем разделе.

Запутывание кубитов с помощью управляемого вентиля НЕ

Это последний вентиль в арсенале, необходимом для квантовых вычислений. Управляемый вентиль НЕ (CNOT) представляет собой двухкубитный вентиль с четырьмя вычислительными состояниями.

Для суперпозиции вентиль CNOT с четырьмя базисными состояниями дает 32322.png, где α, β, δ и γ — коэффициенты суперпозиции.

Квантовая схема:

30099.png 

Матричное представление оператора CNOT для базисных состояний:

Символ «плюс» (+) называется управляемым кубитом, а серая точка (под ним) — это управляющий кубит. Вентиль CNOT выполняет простые действия:

• если для управляющего кубита установлено состояние 1, то состояние управляемого кубита меняется на противоположное;

• в противном случае ничего не происходит.

Точнее, если первый бит является управляющим, то:

32331.png значение управляющего кубита 0 — ничего не выполнять;

32341.png значение управляющего кубита 0 — ничего не выполнять;

32351.png значение управляющего кубита 1 — изменить состояние второго на противоположное;

32360.png значение управляющего кубита 1 — изменить состояние второго на противоположное.

Простое представление данных состояний:

32372.png.

32380.png 

32391.png 

32402.png 

32411.png 

32423.png 

Примечание

Вентиль CNOT необходим для запутывания, что критично для всех видов задач, включая квантовую телепортацию, сверхплотное кодирование и практически любой квантовый алгоритм.

Например, для того, чтобы запутать два кубита, нужно применить вентиль Адамара (Н) к первому кубиту и затем вентиль CNOT — ко второму, как показано далее.

30130.png 

Для базисного состояния кубита (2) вентиль Адамара дает 32433.png.

После применения вентиля CNOT состояние второго кубита изменяется на противоположное, если состояние управляющего соответствует 1, то есть 32441.png.

Это создает запутанное состояние между кубитами 1 и 2.

В общем, вентиль CNOT и однокубитные вентили являются мощным арсеналом для квантовых вычислений. Поскольку они позволяют строить унитарные операции на любом количестве кубитов, их называют универсальными для квантовых вычислений. Это означает, что для создания квантового компьютера, который может решить любую квантовую задачу, достаточно использовать однокубитные вентили совместно с вентилем CNOT и вентилями измерения.

Универсальные квантовые вычисления позволяют получить решение быстрее, чем классические

Вы можете задаться вопросом: как все эти схемы и формулы из предыдущего раздела помогут в решении вычислительных задач, которые легче и, скорее всего, дешевле решить в классической системе. Если принять во внимание так называемую битовую мощность классической системы:

xf(x),

где при заданном входном значении x цель состоит в том, чтобы вычислить функцию f(x) по крайней мере за 2k–1 элементарных операции (где k — это битовая мощность), то универсальные квантовые вычисления могут обеспечить эквивалентную схему примерно того же размера, которая содержит ту же классическую модель:

32451.png.

В этой схеме удивительно то, что иногда существуют быстрые пути решения, обеспечивающие большую мощность квантовых вычислений и более быстрое получение результатов. Это означает, что вы можете вычислить f(x) менее чем за 2k–1 операции. Для некоторых квантовых алгоритмов, таких как факторизация, ускорение является экспоненциальным! Это истинная сила квантовых систем. Итак, теперь, когда вы изучили базовую математическую модель квантовых схем, пришло время переключиться в режим программирования и посмотреть, как все это можно превратить в настоящую компьютерную программу, которая будет выполняться на реальном квантовом устройстве.

Ваша первая квантовая программа

Рассмотрим структуру квантовой программы на простейшем примере. В нем мы создадим один кубит, один классический регистр для его измерения, затем применим вентиль Паули Х (битовое инвертирование) к кубиту и, наконец, измерим его значение. Основной псевдокод программы можно воспроизвести следующим образом.

1. Создать квантовую программу.

2. Создать один или несколько кубитов и классических регистров для их измерения.

3. Создать схему, которая объединит кубиты в устройство выполнения логических операций.

4. Применить квантовые вентили к кубитам для достижения желаемого результата.

5. Измерить кубиты в классических регистрах, чтобы получить конечный результат.

6. Скомпилировать программу. На данном шаге создается JSON-пред­ставление программы в специфическом формате, который будет описан позже в этом разделе.

7. Запустить на моделирующем или реальном квантовом устройстве.

8. Получить результаты.

Теперь подробно рассмотрим как код на Python, так и схему в Composer.

Листинг 4.3. Строение квантовой программы

#############################

import sys

import qiskit

import logging

from qiskit import QuantumProgram

 

# Main sub

def main():

 

    # Создать программу

    qp = QuantumProgram()

 

    # Создать один кубит

    quantum_r = qp.create_quantum_register("qr", 1)

 

    # Создать один классический регистр

    classical_r = qp.create_classical_register("cr", 1)

 

    # Создать схему

    qp.create_circuit("Circuit", [quantum_r], [classical_r])

 

    # Получить схему по названию

    circuit = qp.get_circuit('Circuit')

 

    # Включить ведение журналов

    qp.enable_logs(logging.DEBUG);

 

    # Применить вентиль Паули X к первому кубиту в квантовом регистре "qr"

    circuit.x(quantum_r[0])

 

    # Измерительный вентиль, приводящий нулевой кубит к классическому биту 0

    circuit.measure(quantum_r[0], classical_r[0])

 

    # Серверное моделирующее устройство

    backend = 'local_qasm_simulator'

 

    # Набор исполняемых схем

    circuits = ['Circuit']

 

    # Компиляция вашей программы

    qobj = qp.compile(circuits, backend)

 

    # Запуск на моделирующем устройстве

    result = qp.run(qobj, timeout=240)

 

    # Вывод итоговых результатов

    print (str(result.get_counts('Circuit')))

###########################################

# Linux :main()

# windows if __name__ == '__main__':

    main()

Рассмотрим, что происходит в листинге 4.3.

• В строках 2–5 импортируются нужные библиотеки: sys (системная), qiskit (квантовые классы), logging (для отладки) и QuantumProgram — базового класса для всех программ.

• Затем в строке 11 создается QuantumProgram. Это точка доступа ко всем операциям.

• Для создания списка кубитов воспользуйтесь системным вызовом квантовой программы create_quantum_register(NAME,SIZE), где NAME — это название списка регистров, а SIZE — количество кубитов. В данном случае оно равно 1 (строка 14).

• Для каждого кубита создайте классический регистр для проведения измерений с помощью системного вызова create_classical_register(NAME,SIZE).

• Затем создайте схему, добавив системный вызов create_cir­cuit(NAME,QUANTUM_SET,CLASSIC_SET), где NAME — название схемы, QUANTUM_SET — список кубитов, а CLASSIC_SET — список классических регистров. Схема — это логический блок, содержащий все кубиты и классические регистры (строка 20).

• При желании включите отладку с помощью системного вызова enable_logs(LEVEL), где LEVEL может иметь одно из значений logging.DEBUG, logging.INFO и т.д. (обычные журналы).

• Затем пропустите кубиты через квантовые вентили и выполните их измерения, чтобы получить результаты. В данном случае мы применяем вентиль Паули Х, который изменяет изначальное состояние кубита с 32461.png на 32470.png (строки 25–29).

• Наконец, скомпилируйте программу и запустите моделирующее или реальное устройство. В данном случае выполняем запуск на локальном моделирующем устройстве на Python (local_qasm_simulator) (строки 37–41).

Разработчики под Windows, будьте внимательны! Вам нужно обернуть свою программу в функцию main и затем вызвать ее:

if __name__ == '__main__':

    main()

В Windows так придется сделать, потому что QISKit выполняет программу с помощью асинхронных задач (исполнителей), а при запуске такой задачи подпроцесс сначала выполняет основной модуль. Таким образом, вам нужно защитить основной код, чтобы избежать рекурсивного создания подпроцессов. Я выяснил это на собственном горьком опыте, когда мои программы правильно работали в CentOS, но в Windows выдавали ошибку:

RuntimeError:

    An attempt has been made to start a new process before the current

    process has finished its bootstrapping phase.

 

    This probably means that you are not using fork to start your child

    processes and you have forgotten to use the proper idiom in the

    main module:

 

        if __name__ == '__main__':

            freeze_support()

            …

 

    The "freeze_support()" line can be omitted if the program is not going

    to be frozen to produce an executable.

Это может создать затруднения для новичков в разработке на Python. Теперь запустите программу, чтобы увидеть вывод:

INFO:qiskit._jobprocessor:<qiskit._result.Result object at

0x000000000D99F470>

{'1': 1024}

Результатом является документ в формате JSON {'1': 1024}, где 1 соответствует результату измерения кубита (помните, что мы использовали вентиль X для инверсии бита), а 1024 — количество итераций с таким результатом. Вероятность получения данного результата рассчитывается как отношение количества итераций с ним (1024) к общему количеству итераций программы (1024). В данном случае P = 1024 / 1024 = 1.

Примечание

Квантовые компьютеры — это вероятностные машины. Всем измерениям сопутствует вероятность получения определенного результата.

Листинг 4.3 может также быть описан эквивалентной квантовой схемой, быстро составленной в Composer в IBM Q Experience (рис. 4.4).

04_04.tif 

Рис. 4.4. Эксперимент в Composer для листинга 4.3

Здесь показаны квантовая схема для листинга 4.3, результат эксперимента и сопутствующая ему вероятность. Как видите, схема очень проста: в Composer нужно перетащить вентиль X в положение над нулевым кубитом, а затем выполнить измерение на этом же кубите. Composer покажется вам замечательным инструментом для построения относительно простых схем, их выполнения и визуализации результатов! Теперь давайте заглянем во внутренние компоненты SDK, чтобы увидеть, как обрабатывается этот код.

Внутренние компоненты SDK: компиляция схемы и QASM

На рис. 4.5 показаны внутренние процессы, происходящие при запуске вашей программы.

• QISKit компилирует схему (схемы) программы в документ в формате JSON, который будет отправлен на локальное моделирующее устройство.

• Управляющее устройство анализирует этот документ, запускает схему и возвращает документ в формате JSON без четкой структуры (скрытый от разработчика).

• QISKit обертывает результирующий JSON-документ в объект, доступный для основной программы. Например, вызов result.get_counts('Circuit') извлекает численные данные из этого документа.

30164.png 

Рис. 4.5. Схема последовательности действий между программой, QISKit и локальным моделирующим устройством

Компиляция схемы

В листинге 4.4 показан формат скомпилированной программы перед отправкой на моделирующее устройство. В документе приводятся:

• идентификатор выполнения;

• заголовок с информацией о моделирующем устройстве, включая название, количество кредитов, использованных при выполнении, количество запусков;

• раздел схем, содержащий массив объектов. Каждая схема содержит:

• название;

• заголовок (конфигурацию) с такой информацией, как карта связей кубитов, базовые (физические) вентили, начальное число времени выполнения и т.д.;

• раздел скомпилированной схемы с заголовком, содержащим информацию о кубитах и классических регистрах, массивом операторов (или вентилей), примененных к схеме, и их параметрами.

Листинг 4.4. Формат скомпилированной программы из листинга 4.3

{

    "id": "aA46vJHgnKQko3u5L1QqbUDk31sY2m",

    "config": {

        "max_credits": 10,

        "backend": "local_qasm_simulator",

        "shots": 1024

    },

    "circuits": [{

        "name": "Circuit",

        "config": {

            "coupling_map": "None",

            "layout": "None",

            "basis_gates": "u1,u2,u3,cx,id",

            "seed": "None"

        },

        "compiled_circuit": {

            "operations": [{

                "name": "u3",

                "params": [3.141592653589793, 0.0, 3.141592653589793],

                "texparams": ["\\pi", "0", "\\pi"],

                "qubits": [0]

            }, {

                "name": "measure",

                "qubits": [0],

                "clbits": [0]

            }],

            "header": {

                "number_of_qubits": 1,

                "qubit_labels": [

                    ["qr", 0]

                ],

                "number_of_clbits": 1,

                "clbit_labels": [

                    ["cr", 1]

                ]

            }

        },

        "compiled_circuit_qasm": "OPENQASM 2.0;\ninclude \"qelib1.inc \";

        \nqreg qr[1];\ncreg cr[1];\nu3(3.14159265358979,0,3.14159265358979)

        qr[0];\nmeasure qr[0] -> cr[0];\n"

    }]

}

Для того чтобы отобразить схему, скомпилированную в вашей программе, распечатайте результат шага компиляции с помощью следующей команды:

qobj = qp.compile(circuits, backend)

print(str(qobj))

Примечание

Формат компиляции непрозрачен для программиста и предназначен не для прямого доступа, а через SDK API. Причина в том, что его формат может меняться от версии к версии. Однако всегда хорошо понимать, что происходит за кулисами.

Результаты выполнения

Это ответный документ от локального моделирующего устройства к QISKit. Формат документа показан в листинге 4.5.

Наиболее значимая информация, содержащаяся в нем:

• статус запуска, время выполнения, название моделирующего устройства и т.д.;

• результирующие данные. Их можно получить внутри вашей программы с помощью вызова print(str(result.get_counts('Circuit'))).

Листинг 4.5. Документ с результатами от моделирующего устройства

{

    "backend": "local_qiskit_simulator",

    "id": "aA46vJHgnKQko3u5L1QqbUDk31sY2m",

    "result": [{

        "data": {

            "counts": {

                "1": 1024

            },

            "time_taken": 0.0780002

        },

        "name": "Circuit",

        "seed": 123,

        "shots": 1024,

        "status": "DONE",

        "success": true,

        "threads_shot": 4

    }],

    "simulator": "qubit",

    "status": "COMPLETED",

    "success": true,

    "time_taken": 0.0780002

}

Получить документ с результатами немного сложнее, потому что это объект без четкой структуры, недоступный для пользовательской программы. Тем не менее вы можете сохранить скомпилированную схему из предыдущего раздела и вручную передать ее в моделирующее устройство, чтобы получить результат, показанный в листинге 4.5. Однако это задание оставлено для самостоятельного выполнения. Важно помнить, что документ с результатами, как и формат компиляции, непрозрачен для программиста. Причина в том, что их форматы могут меняться со временем. Тем не менее всегда полезно понимать, что происходит за кадром.

Примечание

Разработчикам моделирующих устройств будет полезно разбираться в форматах компиляции и результатов. Например, вы можете сохранить форматы компиляции и результатов для примера схемы, исправить ошибку в моделирующем устройстве на C++, передать схему и сравнить результаты. Таким образом, ваше моделирующее устройство можно легко интегрировать с SDK, чтобы остальные пользователи могли его опробовать.

Код ассемблера

Скомпилированная схема из листинга 4.4 включает раздел, который содержит трансляцию программы на квантовый ассемблер (QASM), как показано в следующем отрывке:

OPENQASM 2.0;

include "qelib1.inc";

qreg qr[1];

creg cr[1];

x qr[0];

measure qr[0] -> cr[0];

Примечание

QASM полезен только тогда, когда запуск происходит на удаленном моделирующем устройстве, предоставляемом IBM Q Experience.

Локальные моделирующие устройства QISKit

Доступ к реальным квантовым устройствам в IBM Q Experience ограничен кредитами, количество которых уменьшается по мере использования. Таким образом, не стоит запускать совсем простые программы, такие как в листинге 4.3. Для этой цели QISKit предоставляет множество моделирующих устройств, способных удовлетворить все потребности в тестировании. В табл. 4.1 приведен список локальных и удаленных моделирующих устройств, доступных через QISKit и IBM Q Experience на момент написания этой книги.

Таблица 4.1. Список локальных и удаленных моделирующих устройств для IBM Q Experience

Название

Описание

local_qasm_simulator

Моделирующее устройство на Python, поставляемое по умолчанию в комплекте с QISKit. Надо отметить, что оно очень медленное

local_clifford_simulator, также известный как local_qiskit_simulator

Высокопроизводительное моделирующее устройство, написанное на C++, с реалистичной эмуляцией шума и ошибок

ibmqx_qasm_simulator

Высокопроизводительное 24-кубитное удаленное моделирующее устройство на QASM, предоставляемое Q Experience. Это удаленное моделирующее устройство по умолчанию

ibmqx_hpc_qasm_simulator

Тридцатидвухкубитное сверхмощное параллельное моделирующее устройство, предоставляемое Q Experience. Это резервная замена для удаленного моделирующего устройства по умолчанию

В качестве простого упражнения получите список моделирующих и реальных устройств от IBM Q Experience, вставив в браузер следующий URL для REST API: https://quantumexperience.ng.bluemix.net/api/Backends?access_token=ACCESS_TOKEN.

Конечно, вам нужен токен доступа, который можно легко получить с помощью API удаленного доступа, рассмотренного в главе 3. Далее запустим нашу программу на других локальных моделирующих устройствах, включая удаленное моделирующее устройство от IBM Q Experience. Наконец, посмотрим, какое моделирующее устройство самое быстрое.

Запуск на локальном моделирующем устройстве, написанном на C++

QISKit по умолчанию использует моделирующее устройство на чистом Python (local_qasm_simulator). Однако вы можете воспользоваться и быстродействующим моделирующим устройством на C ++ с реалистичным уровнем шума и ошибок, изменив название серверного ПО в своей программе на local_clifford_simulator или local_qiskit_simulator (строка 35 в листинге 4.3). Но прежде, чем задействовать его, следует учесть некоторые предостережения.

• ПользователямLinux. Данное моделирующее устройство работает на основе стандарта C++11, требующего gcc 5.3 или более поздней версии. Фактически это моделирующее устройство так и не было скомпилировано в моих системах CentOS 6 и 7 (вы же можете взять Windows).

• ПользователямWindows. Python использует утилиту CMake для компиляции моделирующего устройства на лету. В общем, источник по умолчанию не предоставляет решение Visual Studio для сборки в Windows. Тем не менее я подготовил одно решение и исправил пару ошибок, с которыми столкнулся в Windows 7.

Совет

Бинарный файл для 64-разрядной Windows для моделирующего устройства на C++ можно найти в исходниках книги по адресу Ch04\qiskit-simulator\qiskit-simulator\x64\Debug. Программа Visual Studio 2017 также предоставляется, если вы хотите скомпилировать его самостоятельно. Убедитесь, что вы скопировали все файлы из этой папки в HOME\Lib\site-packages\qiskit\backends, если их там нет.

Запуск на удаленном моделирующем устройстве

Для запуска на удаленном моделирующем устройстве, предоставляемом IBM Q Experience, нужно немного изменить листинг 4.3. Давайте посмотрим как.

Первое, что нам потребуется, — дескриптор конфигурации IBM Q Experience с параметрами выполнения, приведенными в следующем отрывке:

APItoken = 'YOU-API-TOKEN'

config = {

    'url': 'https://quantumexperience.ng.bluemix.net/api',

    # Следующий код понадобится только пользователям IBM Q

    'hub': 'MY_HUB',

    'group': 'MY_GROUP',

    'project': 'MY_PROJECT'

}

Совет

Предыдущий код должен храниться в отдельном файле (Qconfig.py) в той же папке, что и основная программа. Получите свой токен API из веб-консоли IBM Q Experience, как показано в главе 3, и вставьте его в код. Обратите внимание, что хаб, группу и проект указывают только корпоративные клиенты.

Затем импортируйте упомянутый ранее дескриптор в основную программу:

# Конфигурация Q Experience

import Qconfig

 

# Main sub

def main():

Наконец, замените исполняющее серверное ПО на удаленное моделирующее устройство.

1. Измените название серверного ПО на ibmq_qasm_simulator.

2. Сообщите квантовой программе, что ей нужно использовать IBM Q Experience, установив параметры API с помощью системного вызова qp.set_api(Qconfig.APItoken,Qconfig.config['url']), где APItoken и URL — значения, взятые из дескриптора конфигурации.

3. Выполните в IBM Q Experience посредством системного вызова result=qp.execute(circuits,backend,shots=512,max_credits=3). Обратите внимание на то, что мы не компилируем и не запускаем схему, как раньше. Поэтому вы должны удалить вызовы qobj=qp.compile(circuit,backend) и result=qp.run(qobj,wait=2,timeout=240).

Изменения показаны в следующей команде. Убедитесь, что вы удалили результаты предыдущих компиляций и запустили системные вызовы, иначе программа не будет выполнена:

backend = 'ibmqx_qasm_simulator'

 

# Группа исполняемых схем

circuits = ['Circuit']

# установите APIToken и url для API Q Experience

qp.set_api(Qconfig.APItoken, Qconfig.config['url'])

 

result = qp.execute(circuits, backend, shots=512, max_credits=3, wait=10,

timeout=240)

Наконец, запустите на выполнение и протестируйте. Должен получиться вывод, похожий на следующий:

DEBUG:qiskit.backends._qeremote:Running on remote backend ibmq_qasm_simulator

with job id: 3677ff592e5e5a6fd31a569b0b4faf92

INFO:qiskit._jobprocessor:<qiskit._result.Result object at

0x0000000004A35160>

{'1': 512}

Теперь соберем все вместе и посмотрим, какое моделирующее устройство самое быстрое. Я делаю ставку на C++.

Наиболее быстро моделирующее устройство по результатам сравнения времени выполнения

Я собрал статистику о времени выполнения для всех моделирующих устройств на машине с 64-битным процессором под управлением Windows 7. Невероятно, но самым быстрым оказалось удаленное моделирующее устройство IBM Q Experience, за которым следовали чистый Python и мой личный фаворит C++ (рис. 4.6).

30220.png 

Рис. 4.6. Время выполнения для моделирующих устройств QISKit

Несмотря на то что вызов проходит через сеть, удаленному моделирующему устройству IBM Q Experience удается превзойти другие. Меня поразило то, что интерпретируемое моделирующее устройство на Python может быть быстрее реализации машинного кода. Вероятно, это связано с тем, что вызов машинного кода использует асинхронные задачи для порождения процесса моделирующего устройства на C++ и таким образом приводит к такому замедлению, что код на Python превосходит его. Теперь, когда вы узнали, как запустить программу на моделирующем устройстве, сделаем это на реальном.

Запуск на реальном квантовом устройстве

Изменим программу из предыдущего раздела, чтобы усложнить схему. Листинг 4.6 показывает пример схемы, которая выполняет серию вращений на первом кубите квантового компьютера. Вращения демонстрируют использование физических затворов реального квантового процессора ibmqx4 u1, u2 и u3 для поворота кубита вокруг осей X, Y и Z сферы Блоха на θ, φ или λ градусов.

Примечание

Сфера Блоха — это геометрическое представление кубита, где верхняя часть оси Z отвечает базисному состоянию 32483.png, а нижняя — 32491.png. Поворот вокруг данной оси представляет собой вероятность того, что кубит коллапсирует в определенном направлении при выполнении измерения (рис. 4.7).

30232.png 

Рис. 4.7. Представление кубита на сфере Блоха

Физические вентили, известные также как базовые вентили, важны, потому что на их основе строятся более сложные логические элементы. Таким образом, в листинге 4.6 выполняются следующие шаги.

1. Выделяются пять кубитов и пять классических измерительных регистров, соответствующих пяти кубитам, доступным в процессоре ibmqx4 в Q Experience (строки 17–20).

2. Затем на первом кубите выполняется последовательность вращений с использованием базисных элементов u1, u2 и u3 (строки 29–34).

3. Наконец, на кубите выполняется измерение, а результат сохраняется в классическом регистре.

4. Перед выполнением в качестве серверного ПО устанавливается ibmqx4 (пятикубитный процессор — строка 42), а токен аутентификации и URL-адрес API задаются через set_api(Qconfig.APItoken, Qconfig.config ['url']).

5. Для выполнения на реальном квантовом устройстве используйте системный вызов execute QuantumProgram(NAMES, BACKEND, shots = SHOTS, max_credits = CREDITS, timeout = TIMEOUT), где:

• NAMES — список названий схем;

• SHOTS — количество итераций, выполненных в схеме. Чем оно больше, тем выше точность;

• CREDITS — максимальное количество баллов, которое вы хотите потратить из своего банка кредитов на выполнение (15 — заданное по умолчанию начальное количество). Обратите внимание, что чем больше снимков вы сделаете, тем больше кредитов будет вычтено из банка. Следите за этим, чтобы не исчерпать кредиты;

• TIMEOUT — тайм-аут чтения из удаленной конечной точки.

Примечание

Квантовые программы или эксперименты на Python, выполненные на реальном устройстве, не записываются в разделе Composer-Scores IBM Q Experience. Это связано с тем, что Python неявно использует Jobs из REST API, который вместо этого помещает эксперимент в очередь выполнения. Если хотите записать то, что выполнили, в Composer, можете использовать веб-консоль или REST API, как показано в следующем разделе.

Листинг 4.6. Пример схемы № 2

import sys,time,math

import qiskit

import logging

from qiskit import QuantumProgram

 

# Конфигурация Q Experience

import Qconfig

 

# Main sub

def main():

 

    # Создать программу

    qp = QuantumProgram()

 

    # Создать один кубит

    quantum_r = qp.create_quantum_register("qr", 5)

 

    # Создать один классический регистр

    classical_r = qp.create_classical_register("cr", 5)

 

    # Создать схему

    circuit = qp.create_circuit("Circuit", [quantum_r], [classical_r])

 

    # Включить ведение журналов

    qp.enable_logs(logging.DEBUG);

 

    # Первый физический вентиль: u1(λ) к кубиту 0

    circuit.u2(-4 *math.pi/3, 2 * math.pi, quantum_r[0])

    circuit.u2(-3 *math.pi/2, 2 * math.pi, quantum_r[0])

    circuit.u3(-math.pi, 0, -math.pi, quantum_r[0])

    circuit.u3(-math.pi, 0, -math.pi/2, quantum_r[0])

    circuit.u2(math.pi, -math.pi/2, quantum_r[0])

    circuit.u3(-math.pi, 0, -math.pi/2, quantum_r[0])

 

    # Измерительный вентиль, приводящий кубит 0 к классическому биту 0

    circuit.measure(quantum_r[0], classical_r[0])

    circuit.measure(quantum_r[1], classical_r[1])

    circuit.measure(quantum_r[2], classical_r[2])

 

    # Серверное ПО

    backend = 'ibmqx4'

 

    # Набор исполняемых схем

    circuits = ['Circuit']

 

    # Установить APIToken и URL-адрес API Q Experience

     qp.set_api(Qconfig.APItoken, Qconfig.config['url'])

 

    result = qp.execute(circuits, backend, shots=512, max_credits=3,

    timeout=240)

 

    # Вывод полученных числовых значений

    print ("Job id=" + str(result.get_job_id()) + " Status:" +

    result.get_status())

 

###########################################

if __name__ == '__main__':

    start_time = time.time()

    main()

    print("--- %s seconds ---" % (time.time() — start_time))

Квантовая схема для Composer

Программу из листинга 4.6 также можно создать в Composer от IBM Q Experience с помощью удобного пользовательского интерфейса с поддержкой перетаскивания объектов мышью. Просто перетащите вентиль на гистограмму кубита (рис. 4.8), установите параметры для вентиля и, наконец, сохраните и запустите на моделирующем или реальном устройстве.

30250.png 

Рис. 4.8. Схема для листинга 4.6, созданная в Composer от Q Experience

Тем, кто предпочитает ассемблер, Composer позволяет копировать и вставлять код непосредственно в консоль в режиме ассемблера (рис. 4.9). Он даже проанализирует любые синтаксические ошибки в вашем коде и покажет строки, в которых они содержатся.

Есть несколько способов выполнить ваш эксперимент в IBM Q Experience. Один из самых интересных — воспользоваться их прекрасным REST API.

04_09.tif 

Рис. 4.9. Composer в режиме ассемблера для схемы, показанной на рис. 4.8

Выполнение с помощью вашего любимого клиента REST

Это один из самых интересных способов взаимодействия с Q Experience. Используя простые REST-запросы, вы можете делать практически все, что делаете в Python или Composer:

• получить список устройств серверного ПО;

• получить аппаратные или калибровочные параметры для реальных устройств;

• получить информацию об очереди выполнения задания;

• получить статус задания или эксперимента;

• добавить или отменить задания;

• выполнить эксперимент и записать его в разделе Composer под названием Scores.

Примечание

REST API позволяет использовать любой язык, чтобы создать собственный интерфейс для взаимодействия с Q Experience (даже браузер). Этот API подробно описан в главе 3.

Существует два способа отправки экспериментов с использованием REST: через API заданий и выполнения. Посмотрим, как это делается.

Запуск через API заданий

Вы можете применить любимый браузерный REST-клиент для отправки эксперимента, приведенного в листинге 4.6. Например, с помощью Chrome YARC (еще один клиент REST) создайте HTTP-запрос POST к конечной точке: https://quantumexperience.ng.bluemix.net/api/Jobs?access_token=ACCESS_TOKEN.

Самое сложное — получить токен доступа или ключ доступа. Для этого вы должны пройти аутентификацию, используя свой токен API или имя пользователя и пароль. Обратите внимание на то, что токен API не следует путать с токеном доступа. Чтобы получить токен доступа, вы должны выполнить запрос аутентификации (см. раздел «Удаленный доступ через REST API» главы 3).

Примечание

YARC от Chrome позволяет создавать запросы REST и сохранять их как избранные. Создайте запрос аутентификации для IBM Q Experience, как описано в главе 3, сохраните его как избранный и используйте каждый раз для получения токена доступа при тестировании других вызовов REST API.

Полезные данные запроса представляют собой документ в формате JSON, показанный в листинге 4.7. Формат описан в табл. 4.2.

Таблица 4.2. Формат запроса для API заданий

Ключ

Описание

qasms

Массив программ на ассемблере, записанных в одну строку и разделенных символами конца строки (\n)

Shots

Количество итераций вашего кода

backend

Описание серверного ПО. В данном случае это ibmqx4

maxCredits

Подсказка о том, сколько кредитов будет вычтено из баланса вашего счета

Листинг 4.7. HTTP-запрос для API заданий

{

    "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

}

Получив токен доступа, скопируйте и вставьте полезные данные из листинга 4.7 в свой REST-клиент, отправьте и дождитесь ответа. Если все идет хорошо, вы должны увидеть ответ, похожий на приведенный в листинге 4.8.

Листинг 4.8. HTTP-ответ от Q Experience

{

    "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",

            "status": "WORKING_IN_PROGRESS",

            "executionId": "e9d758c3480a54a6455f72c84c5cc2a6"

        }

    ],

    "shots": 1024,

    "backend": {

        "id": "c16c5ddebbf8922a7e2a0f5a89cac478",

        "name": "ibmqx4"

    },

    "status": "RUNNING",

    "maxCredits": 3,

    "usedCredits": 3,

    "creationDate": "2018-04-24T00:12:07.847Z",

    "deleted": false,

    "id": "33d58594fcb7204e4d2ccdb65cd3c88c",

    "userId": "ef072577bd26831c59ddb212467821db"

}

Частично формат ответа описан в табл. 4.3.

Таблица 4.3. Формат ответа для API заданий

Ключ

Описание

qasms

Массив объектов, который содержит:

• отправленный код;

• статус времени выполнения — WORKING_IN_PROGRESS, COMPLETED или FAILED;

• идентификатор выполнения для кода

shots

Количество итераций эксперимента

backend

Объект, содержащий такую информацию о серверном ПО, как название и идентификатор

status

Общий статус задания — RUNNING, COMPLETED или FAILED

maxCredits

Максимальное количество кредитов, используемое для этого запуска

usedCredits

Реальное количество кредитов, потраченных на запуск

creationDate

Дата создания задания

deleted

Истинно, если был отправлен запрос на удаление задания, иначе ложно.

(Отмененные или удаленные задания удаляются из очереди не сразу, а через некоторое время)

id

Идентификатор задания

userId

Идентификатор хозяина

Примечание

API заданий (а также выполнения) не документированы и не предназначены для прямого доступа в данный момент. Таким образом, со временем формат ответа может меняться. Возможно, в будущем это изменится и REST API станет частью официального SDK. Между тем наши с вами результаты могут различаться.

Запуск через API выполнения

Основное различие между API выполнения и заданий заключается в том, что первый регистрирует эксперимент в Composer. Чтобы увидеть, как это происходит, создайте HTTP-запрос POST к конечной точке: https://quantumexperience.ng.bluemix.net/api/codes/execute?access_token=TOKEN&shots=1&seed=SEED&deviceRunType=ibmqx4.

Параметры запроса:

• access_token — ваш токен доступа;

• shots — количество итераций эксперимента;

• seed — случайное начальное число для выполнения (требуется только при запуске на моделирующем устройстве);

• deviceRunType — название устройства, на котором будет проводиться эксперимент.

Полезные данные запроса приведены в листинге 4.9. Каждый эксперимент должен иметь название. Тип кода — QASM2, ассемблерный код должен быть записан в одну строку, разделенную символами конца строки (\n).

Листинг 4.9. Полезные данные HTTP-запроса API выполнения

{

    "name": "Experiment #20180410193125",

    "codeType": "QASM2",

    "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"

}

Отправьте запрос, используя свой REST-клиент, и дождитесь результата. В листинге 4.10 приведен краткий формат ответа для эксперимента.

Совет

Избавьте себя от головной боли. Всегда проверяйте, подключено ли устройство к сети и записан ли код на qasm в одну строку, включающую символы конца строки (\n), иначе у вас будет много проблем. Дважды и трижды проверьте это, или ваш запрос в большинстве случаев не будет успешно выполнен.

Листинг 4.10. Формат ответа для API выполнения

{

    "startDate": "2018-04-24T22:31:23.555Z",

    "modificationDate": 1524609083555,

    "typeCredits": "plan",

    "status": {

        "id": "WORKING_IN_PROGRESS"

    },

    "deviceRunType": "real",

    "ip": {

        "ip": "172.58.152.206",

        "country": "United States",

        "continent": "North America"

    },

    "shots": 1,

    "paramsCustomize": {},

    "deleted": false,

    "userDeleted": false,

    "id": "1203b1158e6ae537e8b770cb8049a6ae",

    "codeId": "e0f5c573eef75581cf16bce4187ecab8",

    "userId": "ef072577bd26831c59ddb212467821db",

    "infoQueue": {

        "status": "PENDING_IN_QUEUE",

        "position": 108

    },

    "code": {

        "type": "Algorithm",

        "active": true,

        "versionId": 1,

        "idCode": "e86d38c389f4449e62756922a1aa5729",

        "name": "Experiment #201",

            "jsonQASM": {

            "gateDefinitions": [],

            "topology": "3b8e671a5a3b56899e6e601e6a3816a1",

            "playground": [

                {

                    "name": "q",

                    "line": 0,

                    "gates": [

                        …

                    ]

                },

                {

                    "name": "q",

                    "line": 4,

                    "gates": [

                        {

                            "name": "measure",

                            "qasm": "measure",

                            "position": 10,

                            "measureCreg": {

                                "line": 5,

                                "bit": 4

                            }

                        }

                    ]

                },

                {

                    "name": "c",

                    "line": 0

                }

            ],

            "numberGates": 7,

            "hasMeasures": true,

            "numberColumns": 11,

            "include": "include \"qelib1.inc\";"

        },

        "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",

        "codeType": "QASM2",

        "creationDate": "2018-04-24T22:31:22.561Z",

        "deleted": false,

        "orderDate": 1524609083391,

        "userDeleted": false,

        "isPublic": false,

        "id": "e0f5c573eef75581cf16bce4187ecab8",

        "userId": "ef072577bd26831c59ddb212467821db"

    }

}

В этом ответе содержится много информации, причем большая часть данных хорошо понятна. Тем не менее в табл. 4.4 описаны наиболее важные значения.

Таблица 4.4. Информация, возвращаемая для API выполнения

Ключ

Описание

status

Статус выполнения. Может принимать одно из следующих значений: WORKING_IN_PROGRESS, COMPLETED или FAILED

deviceRunType

Устройство, на котором будет запущен эксперимент: real (для реальных устройств) или simulator (для моделирующих устройств)

infoQueue

Информация об очереди выполнения, содержащая:

• статус — PENDING_IN_QUEUE;

• позицию в очереди

code

Очень подробное описание эксперимента, включающее:

• квантовые вентили, параметры, позицию и многое другое;

• код ассемблера;

• разную информацию: название, тип, статус, версию и т.д.

Совет

После получения ответа войдите в консоль IBM Q Experience. Назва­ние эксперимента должно отображаться в разделе Quantum Scores в Com­poser.

Квантовый ассемблер: мощь, скрытая за кулисами

Вы, скорее всего, поняли, что происходит за кулисами, когда эксперимент выполняется в Composer или REST-клиенте. Схема транслируется в квантовый ассемблер (QASM), а затем выполняется на реальном или моделирующем устройстве. Квантовый ассемблер является промежуточным представлением кода высокого уровня Python и результатом сотрудничества между IBM Q Experience и сообществом разработчиков ПО с открытым исходным кодом.

Примечание

QASM основан на классическом аналоге, который стал своего рода утраченным искусством. Тем не менее он не столь пугающий, как его собрат. Фактически в его основе действительно лежит грамматика классического ассемблера.

Формально жизненный цикл вашей программы на Python или схемы в Q Experience можно описать как нечто среднее между квантовой и классической частями вычислений со следующими шагами.

• Компиляция. Это автономный шаг, выполняемый на классическом компьютере. Когда работает схема, написанная на Python или составленная в Composer, классический компилятор переводит высокоуровневое представление (например, на Python) в промежуточное представление на QASM. Этот шаг имеет следующие характеристики:

• конкретные параметры задачи еще неизвестны;

• не требуется взаимодействие с квантовым компьютером;

• можно скомпилировать классические процедуры в объектную программу и выполнить первоначальную оптимизацию. Например, программа на Python, приведенная в листинге 4.6, и соответству­ющая схема, составленная в Composer, транслированы в ассемблер, показанный в листинге 4.11.

Листинг 4.11. Код QASM для программы на Python из листинга 4.6

include "qelib1.inc";

qreg qr[5];

creg cr[5];

u2(-4.18879020478639,6.28318530717959) qr[0];

u2(-4.71238898038469,6.28318530717959) qr[0];

u3(-3.14159265358979,0,-3.14159265358979) qr[0];

u3(-3.14159265358979,0,-1.57079632679490) qr[0];

u2(3.14159265358979,-1.57079632679490) qr[0];

u3(-3.14159265358979,0,-1.57079632679490) qr[0];

measure qr[0] -> cr[0];

measure qr[1] -> cr[1];

measure qr[2] -> cr[2];

• Генерация схемы. Код QASM из предыдущего шага передается на фазу генерации цепи. Этот шаг выполняется на классическом компьютере, где известны конкретные параметры задачи и может произойти определенное взаимодействие с квантовым компьютером. Шаг имеет следующие характеристики:

• это онлайн-фаза (происходит на квантовом компьютере);

• выход представляет собой набор квантовых цепей или квантовых базовых блоков с соответствующими классическими инструкциями управления и классическим объектным кодом, необходимым во время выполнения.

• Выполнение. Этот шаг производится на физическом квантовом компьютере. Вход представляет собой набор квантовых схем, выраженных с использованием промежуточного представления квантовых схем. Они выполняются на контроллере низкого уровня, а выход представляет собой набор результатов измерений, возвращаемых из контроллера высокого уровня.

• Постобработка. Выполняется на классическом компьютере, будет получен набор обработанных результатов измерений. Выходные данные являются окончательным результатом квантовых вычислений (рис. 4.10).

04_10.tif 

Рис. 4.10. Результаты постобработки для жизненного цикла схемы из листинга 4.6

В общем, синтаксис квантового ассемблера не так страшен по сравнению с его классическим аналогом. На самом деле программировать напрямую на квантовом ассемблере оказывается проще и быстрее, чем на Python. Далее представлен набор простых приемов, которые можно использовать, если вы решите написать код непосредственно на QASM.

• Всегда начинайте с включения заголовка qelib1.inc. Он содержит аппаратные примитивы Q Experience (квантовые вентили). Логические элементы, представленные в этой библиотеке, описаны в табл. 4.5 для однокубитных и в табл. 4.6 для многокубитных вентилей.

Таблица 4.5. Однокубитные вентили, представляемые квантовым ассемблером

Название

Описание

u3(theta,phi,lambda)

Однокубитный трехпараметрический двухимпульсный вентиль

u2(phi,lambda)

Однокубитный двухпараметрический одноимпульсный вентиль

u1(lambda)

Однопараметрический однокубитный вентиль

Id

Эквивалент матрицы тождественного преобразования или u(0,0,0)

X

Паули X или σx или инверсия битов

Y

Паули Y или σy

Z

Паули Z или σz

rx(theta)

Поворот вокруг оси X на θ градусов

ry(theta)

Поворот вокруг оси Y на θ градусов

rz(Phi)

Поворот вокруг оси Z на θ градусов

H

Адамара — переводит одиночный кубит в суперпозицию состояний

S

Квадратный корень из Z — вентиль фазового сдвига sqrt(Z)

Sdg

S — эрмитово сопряжение S. Алгебраически это определено как комплексное сопряжение транспонированной матрицы sqrt(Z)

T

Вентиль фазового сдвига sqrt(S)

Tdg

Т — эрмитово сопряжение sqrt(S)

Таблица 4.6. Многокубитные вентили, представляемые квантовым ассемблером

Название

Описание

cx c,t

Управляемое НЕ (CNOT) — инвертирует состояние второго кубита (t), только если управляющий кубит (с) имеет значение 1. Используется для запутывания кубитов

cz a,b

Управляемый фазовый сдвиг — применяет фазовый сдвиг, только если управляющий кубит (а) имеет значение 1

cy a,b

Управляемый Y — применяет Паули Y, только если управляющий кубит (а) имеет значение 1

ch a,b

Управляемый H — переводит кубит (b) в суперпозицию, только если управляющий кубит (а) имеет значение 1

ccx a,b,c

Трехкубитный вентиль Тоффоли — инвертирует состояние кубита с, только если управляющие кубиты а и b имеют значение 1

• Объявить регистр (массив) кубитов просто. Например, объявление регистра, состоящего из пяти кубитов: qregqr[5]. (Примечание: все инструкции разделяются точкой с запятой.)

• Чтобы объявить регистр, состоящий из пяти классических битов, используйте cregcr[5].

• Чтобы применить вентиль к определенному кубиту, просто введите название вентиля и управляемый кубит. Например, чтобы перевести первый кубит в суперпозицию (для квантового генератора случайных чисел), используйте hq[0].

• Последним шагом в вашей программе всегда должно быть измерение кубита. Например, чтобы измерить кубит, который мы перевели в состояние суперпозиции, и сохранить его в первом классическом регистре, возьмите measureqr[0]->cr[0].

Обратите внимание, что квантовые компьютеры являются вероятностными машинами, следовательно, невозможно узнать, в каком именно состоянии находится кубит (это запрещено квантовой механикой). Таким образом, мы получаем лишь вероятность того, что кубит находится в состоянии 0 или 1. Для простого квантового генератора случайных чисел на нулевом кубите hq[0], упомянутом ранее, мы можем использовать вероятность состояния 1 в качестве случайного числа. Это можно представить в виде графика, выдаваемого Composer в IBM Q Experience, когда результаты собираются после выполнения кода ассемблера (см. рис. 4.9).

Вы сделали первый шаг по карьерной лестнице в качестве квантового программиста, работающего в облаке. Используя высокоуровневый SDK для Python и мощный механизм квантового ассемблера, можно проводить эксперименты на потрясающей платформе IBM Q Experience. Эти навыки окажутся полезными через несколько лет, когда квантовые компьютеры начнут появляться в центрах обработки данных. В следующей главе мы перейдем на новый уровень, рассмотрев набор алгоритмов, которые демонстрируют волшебство квантовой механики в вычислениях. Так что читайте дальше.

Назад: 3. IBM Q Experience: уникальная платформа для квантовых вычислений в облаке
Дальше: 5. Запускаем движки: от квантовой генерации случайных чисел до телепортации с остановкой на сверхплотном кодировании

Treyfecah
Ничо так --- Я думаю, что Вы не правы. Пишите мне в PM, поговорим. скачать фифа, скачать fifa и fifa 15 скачать фифа
Kbcxsame
compare prescription prices Viagra Oral Jelly canada pharma limited
JbnvJinge
payday loans batesville ar payday loans delray beach fl cashback payday advance careers
Kvaxsame
vanquis payday loans loan advance.com cash advance in ky
itelsAni
Female Cialis Soft Fildena nearest cvs pharmacy store canadian pharmacy for dogs ’
DefAmurnGtv
london drugs canada Nemasole Oxytrol Zithromax ’
iMabeHtf
canada drugs review safeway pharmacy store 1818 24 hours pharmacy store solutions rx pharmacy ’
RnhAmurnDev
long term use of prilosec omeprazole and alzheimer's prilosec price best time to take omeprazole ’
nutleVfs
amlodipine norvasc side effects amlodipine besylate drug class norvasc 10 mg tablet amlodipine benazepril side effects ’