Не секрет, что Q# и Quantum Development Kit позволяют легко писать квантовые программы и запускать их на симуляторах и на оборудовании через службу Azure Quantum, с использованием Python, .NET или даже через Jupyter Notebook. Более того, инфраструктура, которая поддерживает все эти различные способы использования Q#, также позволяет создавать новые и захватывающие способы написания и выполнения квантовых программ. В этой статье мы немного рассмотрим эту инфраструктуру и то, как вы можете использовать эту инфраструктуру для подключения Q# к вашим любимым языкам и платформам.

Python и Interactive Q#

Для начала давайте посмотрим, как Q# подключается к таким платформам, как Python и Jupyter. Обе платформы в значительной степени ориентированы на интерактивное использование, при котором программы не обязательно предварительно компилируются, а создаются разработчиками по частям.

Само по себе это сильно отличается от того, как можно использовать Q# из командной строки или при создании приложения .NET, использующего квантовые вычисления. Чтобы Q# работал в интерактивной среде, Quantum Development Kit также включает IQ#, сокращенно от Interactive Q# и следуя схеме именования, популяризированной IPython, IJulia и другими подобными инструментами. Ядро IQ# использует компилятор и среду выполнения Q# в качестве библиотеки, что позволяет ему на лету вызывать компилятор и среду выполнения Q#. Это тот же подход, который используется многими другими инструментами, включенными в Quantum Development Kit, такими как интерфейс командной строки компилятора Q# (qsc.exe) или языковой сервер, используемый расширениями Visual Studio Code и Visual Studio 2019.

Использование ядра IQ# из Q# notebook
Использование ядра IQ# из Q# notebook

Когда ядро IQ# получает сообщения от клиентов Jupyter, оно передает исходный код Q# компилятору, возвращая программы, которые можно запускать на симуляторах или отправлять в службы Azure Quantum. Такой подход позволяет нам подключать интерактивные среды, такие как Jupyter, к остальной части Quantum Development Kit. С точки зрения платформы Jupyter ядро IQ# - это просто еще один исполняемый файл; То, что ядро IQ# написано с использованием .NET, на тот момент является деталью реализации.

Тот же подход также позволяет использовать Python в качестве основного языка для ваших квантовых программ. В частности, пакет jupyter_client можно использовать для вызова из хост-программы Python в любое ядро, распознаваемое платформой Jupyter. Пакет qsharp для Python использует jupyter_client для загрузки IQ#, отправки команд ядру и получения обратно расширенных отображаемых данных. За кулисами ваша хост-программа Python действует как другой клиент Jupyter, обмениваясь сообщениями с ядром IQ#, чтобы вы могли создавать свою программу Q# из среды со сценариями.

Использование ядра IQ# из программы Python
Использование ядра IQ# из программы Python

Вызов квантовых программ из Julia? Lua…? PowerShell…‽

Однако IQ# - это не просто исполняемая программа. Большая часть логики, которую IQ# использует для взаимодействия с компилятором Q# и средой выполнения, упакована в виде собственной библиотеки, доступной на NuGet.org в виде пакетов Microsoft.Quantum.IQSharp.Core и Microsoft.Quantum.IQSharp.Jupyter. Эти два пакета могут использоваться любыми другими приложениями .NET для реализации интеграции вашего собственного языка для Q#.

Например, мы можем написать небольшое приложение C#, которое использует библиотеку IQ#, чтобы предоставить компилятору Q# и среде выполнения серию простых сообщений JSON, которые легко отправлять и получать с других языков. Используя JSON.jl, мы можем написать клиент для этого нового приложения в Julia и использовать его для интерактивного создания квантовых приложений из среды Julia.

Вызов в Q# из Julia
Вызов в Q# из Julia

Этот подход не ограничивается только Julia, но может использоваться в большинстве мест, где вы можете вызывать приложения командной строки. То же самое приложение C#, которое мы использовали выше, также можно быстро адаптировать, чтобы мы могли вызывать Q# из других языков, таких как Lua или даже PowerShell.

Вызов Q# из Lua
Вызов Q# из Lua
Вызов Q# из PowerShell
Вызов Q# из PowerShell

→ Изучите примеры кода

Написание ботов с внедрением зависимостей

Однако мы можем пойти еще дальше и использовать IQ# в качестве библиотеки для встраивания Q# в веб-приложения и чат-ботов. Различные компоненты, составляющие IQ#, представлены пакетами Microsoft.Quantum.IQSharp.Core и Microsoft.Quantum.IQSharp.Jupyter как службы, которые можно добавлять в ваши собственные приложения с помощью внедрения зависимостей ASP.NET Core.

Изучим, что нужно сделать, чтобы добавить IQ# к боту в Discord:

public void ConfigureServices(IServiceCollection services)
{
     services
     // Добавьте службы, необходимые для работы в качестве приложения Discord. 
        .AddDiscord()
            // Добавьте службы логирования. 
            .AddLogging(
                builder => builder
                    .SetMinimumLevel(LogLevel.Debug)
                    .AddAzureWebAppDiagnostics()
                    .AddConsole()
                )
        // Добавьте сервисы, уникальные для этого бота. 
        .AddSingleton<CommandHandler>()
        .AddSingleton<Bot>();

    // Добавьте сервисы, необходимые для работы с компилятором Q# и средой выполнения. 
    services.AddIQSharp();

    // Добавьте необходимые службы.
    services.AddRazorPages();
    services.AddServerSideBlazor();
}

Здесь AddIQSharp - это метод расширения, предоставляемый библиотекой IQ#, который добавляет службы IQ# в существующую коллекцию служб. Поскольку Discord.NET написан с использованием той же инфраструктуры внедрения зависимостей, вызов AddIQSharp позволяет нам немедленно запрашивать службы IQ# так же, как мы бы предоставляли сервисы Discord.NET:

public class SimulateModule : ModuleBase<SocketCommandContext>
{
    private readonly ISnippets snippets;
    private readonly IWorkspace workspace;
    private readonly ILogger logger;
    private static readonly Emoji waiting = new Emoji("⌛");

    public SimulateModule(
        ISnippets snippets, IWorkspace workspace,
        ILogger<SimulateModule> logger)
    {
        this.snippets = snippets;
        this.workspace = workspace;
        this.logger = logger;
    }

    // ...

Здесь команда нашего бота %simulate использует свой конструктор для запроса служб IQ#, таких как его фрагменты кода и менеджеры рабочей области, а также средство ведения журнала ASP.NET Core, используемое для предоставления отладочной информации.

Тот же подход можно использовать даже для предоставления REST API для компилятора Q# и среды выполнения! Например, веб-проект в репозитории microsoft/iqsharp использует IQ# вместе с ASP.NET Core, чтобы разрешить использование Q# через HTTP.

Итого

Какие бы инструменты и платформы вы ни любили, Q# и Quantum Development Kit помогут вам максимально эффективно использовать квантовые вычисления. Используя такие инструменты, как библиотека и ядро IQ#, вы можете легко расширить Q# для работы с широким спектром языков, платформ и экосистем.

Комментарии (2)


  1. Fulborg
    26.11.2021 01:15

    А можно для людей не в теме какой-нибудь пример «квантовой программы» и задачи которую она решает?
    Не на уровне «пишем в консоль hello world, но из квартовой программы», а что-то более применимое в реальной жизни?


    1. BkmzSpb
      26.11.2021 13:11
      +2

      Первое, что нужно понять, квантовый компьютер -- это не компьютер "с квантами", а отдельное устройство для решения определенных, весьма специфических задач (по крайней мере сейчас и, вероятно, в ближайшие 10-20 лет). Ближайшая аналогия -- дискретная видеокарта. Видеокарта никогда не выполняет код, который пишет "hello world' в консоль, она лишь принимает некий специфический байткод шейдера, какие-то данные (через не самую быструю шину), после чего выполняет какие-то действия внутри себя и либо выдает результаты обратно (например, как результат compute-шейдера), либо выводит их в стороннее устройство -- как кадр вашей любимой игры на подключенные мониторы.

      Квантовый компьютер действует аналогично -- это не замена CPU. Квантовый компьютер так же принимает какой-то код программы -- на данном этапе это последовательность gates, которые определяют, какие операции применяются к каким кубитам. Фактически это квантовые машинные инструкции а не высокоуровневые функции. Далее в квантовый компьютер можно отправить данные -- закодировать начальне состояния кубитов в 0 или 1. После происходит "выпонение" алгоритма. После чего результат можно считать -- измерить состояние каждого кубита (после чего кубиты становятся бесполезными и продолжать вычисления с ними можно только начав с самого начала), при этом все возможные квантовые состояния кубита при измерении дают либо 0 либо 1. Вот тут начинается самое интересное. Если кубит не находится в состоянии "строго 0" или "строго 1", то результат измерения будет случайным, но при этом подчиняясь определенному распределению.

      Так что же это значит?

      1. Выполнив алгоритм один раз, вы не получите никакого результата. Если на выходе вы считываете один кубит и знаете, что ожидамое распределение -- 70% это 1 и 30% это 0, то прогнав данные 10 раз в идеальном случае вы получите 7 измерений 1 и 3 измерений 0, после чего сможете сделать какой-то вывод. Больше прогонов -> лучше статистика, особенно для сложных алгоритмов где вероятности могут слабо отличаться друг от друга.

      2. Особенность квантовых вычислений -- в их скорости, а точнее в количестве операций, необходимых для получения результата. Иными словами, сложность алгоритмов -- меньше, и при определенном стечении обстоятельств решение некоторых задач, даже учитывая особенности, описанные в пункте 1, будет происходить на порядки быстрее, чем на обычном CPU. Это в свою очередь позволяет достичь "квантового превосходства" (quantum supremacy) -- решение с помощью квантового компьютера задачи, которую ни один обычный компьютер/суперкомпьютер не сможет решить за разумное время ( = ни один гипотетический суперкомпьютер с самыми лучшими чипами на планете не сможет решить проблему).

      Из совсем простых примеров -- алгоритм Гровера, который фактически позвояет найти элемент в неупорядоченной коллекции за N^0.5, вместо классического N. Не самый значительный прирост (квадратичные а не экспоненциальный), тем не менее на очень больших данных разница будет колоссальна.

      Чуть более сложный, но при этом намного более эффективный алгоритм -- алгоритм Шора, который факторизует целые числа (ищет все простые делители). Если совсем на пальцах, классический алгоритм имеет сложность порядка exp(log(N)), а алгоритм Шора -- log(N) (опуская множители и полиномиальные степени которые не влияют на общую картину). Это в свою очередь ставит под угрозу стандартне методы шифрования, которые полагаются на невозможность быстрой факторизации классическими методами.

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