Поделиться через


Создание проектов и пользовательских библиотек и управление ими Q#

В этой статье вы узнаете, как создавать, управлять и совместно использовать Q# проекты. Q# проекты — это структуры папок с несколькими Q# файлами, которые могут получить доступ к операциям и функциям друг друга. Проекты полезны для логического упорядочения исходного кода. Вы также можете использовать проекты в качестве пользовательских библиотек, к которым можно получить доступ из внешних источников.

Необходимые компоненты

  • Рабочая область Azure Quantum по подписке Azure. Сведения о создании рабочей области см. в статье Создание рабочей области Azure Quantum.
  • Visual Studio Code с установленным расширением Azure Quantum Development Kit и Python .
  • Учетная запись GitHub, если вы планируете опубликовать внешний проект в общедоступном репозитории GitHub.

Для запуска программ Python также требуется:

Как Q# работают проекты

Проект Q# содержит файл манифеста Q# с именем qsharp.json и один или несколько файлов *.qs в указанной структуре папок. Когда пользователь открывает файл *.qs в VS Code или задает project_root файл Jupyter Notebook или Python, компилятор выполняет поиск в окружающей иерархии папок для файла манифеста и определяет область проекта. Если файл манифеста не найден, компилятор работает в одном режиме. Проект можно создать Q# вручную или непосредственно в VS Code.

Внешний Q# проект — это стандартный Q# проект, который находится в другом каталоге или в общедоступном репозитории GitHub и выступает в качестве пользовательской библиотеки. Внешний проект использует export инструкции для определения функций и операций, к которым можно обращаться внешними программами. Программы определяют внешний проект как зависимость в файле манифеста и используют import инструкции для доступа к элементам (операциям, функциям, структуры и пространствам имен) во внешнем проекте. Дополнительные сведения см. в разделе "Использование проектов в качестве внешних зависимостей".

Q# Определение проекта

Q# Проект определяется наличием файла манифеста с именем qsharp.json и папкой src (которая содержит Q# исходные файлы), оба из которых должны находиться в корневой папке проекта. Для Q# программ и внешних проектов Q# компилятор автоматически обнаруживает папку проекта. Для программ Python и Jupyter Notebook необходимо указать папку Q# проекта с вызовомqsharp.init. Однако структура папок проекта остается одинаковой Q# для всех типов программ.

Структура папок и иерархия для Q# проекта.

Определение папки проекта (Q# программы)

При открытии файла *.qs в VS Code Q# компилятор выполняет поиск вверх в структуре папок для файла манифеста. Если он находит файл манифеста, компилятор будет содержать все Q# файлы в каталоге /src или любой из его подкаталогов. Элементы каждого файла становятся доступными для всех остальных файлов в проекте.

Например, учитывая эту структуру папок:

  • Teleportation_project
    • qsharp.json
    • src
      • Main.qs
      • TeleportOperations
        • TeleportLib.qs
        • PrepareState
          • PrepareStateLib.qs

При открытии файла /src/TeleportOperation/PrepareState/PrepareStateLib.qsQ# компилятор:

  1. Проверяет /src/TeleportOperation/PrepareState/ для qsharp.json.
  2. Проверяет значение /src/TeleportOperation для qsharp.json.
  3. Проверяет /src для qsharp.json.
  4. Проверяет / наличие qsharp.json.
  5. / Устанавливает в качестве корневого каталога проекта и включает все файлы *.qs в корневом каталоге проекта в соответствии с параметрами файла манифеста.

Создание файла манифеста

Файл манифеста — это простой файл .json с именем qsharp.json , который может включать поля авторов, лицензий и lints . Минимальный жизнеспособный файл манифеста — это строка {}. При создании проекта в VS Code создается минимальный Q# файл манифеста.

{}

Примеры файлов манифеста

Ниже приведены некоторые примеры того, как файлы манифеста Q# могут определять область проекта.

  • В этом примере автор является единственным полем, поэтому все файлы *.qs в этом каталоге и все его подкаталогы включены в Q# проект.

    {
        "author":"Microsoft",
        "license": "MIT"
    }
    
  • В проекте также можно использовать файл манифеста для точной Q# настройки параметров VS Code Q# Linter. По умолчанию три правила Linter:

    • needlessParens: default = allow
    • divisionByZero: default = warn
    • redundantSemicolons: default = warn

    Используя файл манифеста, можно задать для каждого правила значение allow, warnили error, например,

    {
        "author":"Microsoft",
        "lints": [
            {
              "lint": "needlessParens",
              "level": "allow"
            },
            {
              "lint": "redundantSemicolons",
              "level": "warn"
            },
            {
              "lint": "divisionByZero",
              "level": "error"
            }
          ]
    }
    
  • Вы также можете использовать файл манифеста для определения внешнего проекта как зависимости и удаленного доступа к операциям и функциям в этом внешнем Q# проекте. Дополнительные сведения см. в разделе "Использование проектов в качестве внешних зависимостей".

Q# Требования к проекту и свойства

Следующие требования и конфигурации применяются ко всем Q# проектам.

  • Все файлы *.qs, которые необходимо включить в проект, должны находиться под папкой с именем src, которая должна находиться под корневой папкой объекта Q#. При создании Q# проекта в VS Code /src папка создается автоматически.

  • Файл манифеста должен находиться на том же уровне, что и папка src . При создании проекта в VS Code минимальный Q# файл создается автоматически.

  • Используйте import инструкции для ссылки на операции и функции из других файлов в проекте.

    import MyMathLib.*;  //imports all the callables in the MyMathLib namespace
    ...
        Multiply(x,y);
    

    или ссылка на них по отдельности с пространством имен

    MyMathLib.Multiply(x,y);  
    

Только для Q# проектов

  • Только один файл *.qs в Q# проекте может иметь точку входа, определенную одной Main() операцией.
  • Файл *.qs с определением точки входа можно найти на любом уровне ниже файла манифеста.
  • Любая операция или функция, кэшируемая из файла *.qs в любом месте проекта, отображается в прогнозном тексте Q# в VS Code.
  • Если пространство имен для выбранной операции или функции еще не импортировано, VS Code автоматически добавляет необходимую import инструкцию.

Действия по созданию Q# проекта

Эти шаги применяются ко всем Q# проектам.

  1. В проводнике VS Code щелкните правой кнопкой мыши папку, которую вы хотите использовать для корневой Q# папки проекта, и выберите "Создать Q# проект" или откройте папку и выберите команду View > Command Palette >Q#: Create a Q# project....

  2. VS Code создает минимальный файл манифеста в папке и добавляет /src папку с файлом Main.qs шаблона.

  3. Измените файл манифеста по мере необходимости. См . примеры файлов манифеста.

  4. Добавьте и упорядочение Q# исходных файлов в папке /src .

  5. Если вы обращаетесь к Q# проекту из программы Python или Jupyter Notebook, задайте путь к корневой папке с помощью qsharp.init. В этом примере предполагается, что программа находится в папке Q# /src проекта:

    qsharp.init(project_root = '../Teleportation_project')
    
  6. Если вы используете только Q# файлы в VS Code, при открытии Q# файла компилятор ищет файл манифеста, определяет корневую папку проекта, а затем сканирует вложенную папку для файлов *.qs.

Примечание.

Вы также можете вручную создать файл манифеста и папку /src на шаге 2.

Пример проекта

Эта программа квантового Q# телепортации является примером проекта на основе структуры одной папки, показанной ранее, и выполняется на локальном симуляторе в VS Code. Сведения о запуске программы на оборудовании Azure Quantum или сторонних симуляторах см. в статье "Начало работы с Q# программами и VSCode ", чтобы выполнить компиляцию программы и подключиться к рабочей области Azure.

В примере используется эта структура каталогов:

  • Teleportation_project
    • qsharp.json
    • src
      • Main.qs
      • TeleportOperations
        • TeleportLib.qs
        • PrepareState
          • PrepareStateLib.qs

Файл манифеста содержит поля автора и лицензии :

{
    "author":"Microsoft",
    "license":"MIT"
}

Q# исходные файлы

Основной файл Main.qs содержит точку входа и ссылается на TeleportOperations.TeleportLib пространство имен из TeleportLib.qs.


    import TeleportOperations.TeleportLib.Teleport;   // references the Teleport operation from TeleportLib.qs

    operation Main() : Unit {
        use msg = Qubit();
        use target = Qubit();

        H(msg);
        Teleport(msg, target);    // calls the Teleport() operation from TeleportLib.qs
        H(target);

        if M(target) == Zero {
            Message("Teleported successfully!");
        
        Reset(msg);
        Reset(target);
        }
    }

TeleportLib.qs определяет Teleport() операцию и вызывает PrepareBellPair() операцию из PrepareStateLib.qs.


    import TeleportOperations.PrepareState.PrepareStateLib.*;     // references the namespace in PrepareStateLib.qs
 
    operation Teleport(msg : Qubit, target : Qubit) : Unit {
        use here = Qubit();

        PrepareBellPair(here, target);      // calls the PrepareBellPair() operation from PrepareStateLib.qs
        Adjoint PrepareBellPair(msg, here);

        if M(msg) == One { Z(target); }
        if M(here) == One { X(target); }

        Reset(here);
    }

Файл PrepareStateLib.qs содержит стандартную операцию повторного использования для создания пары Bell.

    
    operation PrepareBellPair(left : Qubit, right : Qubit) : Unit is Adj + Ctl {
        H(left);
        CNOT(left, right);
    }

Запуск программ

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

Чтобы запустить эту программу, откройте файл Main.qs в VS Code и нажмите кнопку "Выполнить".

Q# Настройка проектов в качестве внешних зависимостей

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

Чтобы использовать Q# проект в качестве внешней зависимости, необходимо:

  • Добавьте внешний проект в качестве зависимости в файл манифеста вызывающего проекта.
  • Если внешний проект опубликован в GitHub, добавьте свойство files в файл манифеста внешнего проекта.
  • Добавьте export инструкции во внешний проект.
  • Добавьте import инструкции в вызывающий проект.

Настройка файлов манифеста

Внешние Q# проекты могут находиться на локальном или сетевом диске или публиковаться в общедоступном репозитории GitHub.

Файл манифеста вызывающего проекта

Чтобы добавить зависимость во внешний проект в общую папку диска, определите зависимость в файле манифеста вызывающего проекта.

{
    "author": "Microsoft",
    "license": "MIT",
    "dependencies": {
        "MyDependency": {
            "path": "/path/to/project/folder/on/disk"
        }
    }
}

где "MyDependency" — это определяемая пользователем строка, которая определяет пространство имен при вызове операции. Например, если вы создаете зависимость с именем MyMathFunctions, вы вызовете функцию из этой зависимости MyMathFunctions.MyFunction().

Добавление зависимости в проект, опубликованный в общедоступном репозитории GitHub

{
    "author": "Microsoft",
    "dependencies": {
        "MyDependency": {
            "github": {
                "owner": "GitHubUser",
                "repo": "GitHubRepoName",
                "ref": "CommitHash",
                "path": "/path/to/dependency"
            }
        }
}

Примечание.

Для зависимостей GitHub ссылка ссылается на GitHub refspec. Корпорация Майкрософт рекомендует всегда использовать хэш фиксации, поэтому вы можете полагаться на определенную версию зависимости.

Файл манифеста внешнего проекта

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

{
    "author": "Microsoft",
    "license": "MIT",
    "files": [ "src/MyMathFunctions.qs", "src/Strings/MyStringFunctions.qs" ]
}

Свойство "files" является необязательным для импортируемого "path" внешнего проекта (то есть локального импорта на основе файлов). Это необходимо только для проектов, опубликованных в GitHub.

Использование инструкции экспорта

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

operation Operation_A() : Unit {
...
}
operation Operation_B() : Unit  {
...
}

// makes just Operation_A available to calling programs
export Operation_A;           

// makes Operation_A and Operation_B available to calling programs         
export Operation_A, Operation_B, etc.; 

// makes Operation_A available as 'OpA'
export Operation_A as OpA;             

Использование инструкции импорта

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

{
    "author": "Microsoft",
    "license": "MIT",
    "dependencies": {
        "MyMathFunctions": {
            "path": "/path/to/project/folder/on/disk"
        }
    }
}

вы импортируете вызываемые как

import MyMathFunctions.MyFunction;  // imports "MyFunction()" from the namespace
...

Инструкция import также поддерживает синтаксис и псевдонимы подстановочных карт.

// imports all items from the "MyMathFunctions" namespace
import MyMathFunctions.*;        

// imports the namespace as "Math", all items are accessible via "Math.<callable>"
import MyMathFunctions as Math;   

// imports a single item, available in the local scope as "Add"
import MyMathFunctions.MyFunction as Add;        

// imports can be combined on one line
import MyMathFunctions.MyFunction, MyMathFunctions.AnotherFunction as Multiply; 

Примечание.

В настоящее время используется open инструкция Q#, которая используется для ссылок на библиотеки и пространства имен, по-прежнему поддерживается, но в конечном итоге будет устарела. В то же время можно дополнительно обновить текущие файлы, чтобы использовать инструкцию import . Например, open Microsoft.Quantum.Diagnostics; можно заменить на import Microsoft.Quantum.Diagnostics.*;. Кроме того, обратите внимание, что при использовании инструкции import со стандартными Q# библиотеками можно сократить корневое пространство имен до Std. Например, import Microsoft.Quantum.Diagnostics.*; может быть записано как import Std.Diagnostics.*;.

Пример внешнего проекта

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

  1. Создайте две папки на локальном диске, например "Project_A" и "Project_B".

  2. Создайте проект в каждой Q# папке, выполнив действия, описанные в разделе "Действия по созданию Q# проекта".

  3. В Project_A вызываемая программа скопируйте следующий код в файл манифеста, изменив путь по мере необходимости для Project_B

    {
      "author": "Microsoft",
      "license": "MIT",
      "dependencies": {
        "MyTeleportLib": {
          "path": "/Project_B" 
          }
        }
      }    
    
  4. В Project_A скопируйте следующий код в Main.qs

    import MyTeleportLib.Teleport;   // imports the Teleport operation from the MyTeleportLib namespace defined in the manifest file
    
    operation Main() : Unit {
        use msg = Qubit();
        use target = Qubit();
    
        H(msg);
        Teleport(msg, target);    // calls the Teleport() operation from the MyTeleportLib namespace
        H(target);
    
        if M(target) == Zero {
            Message("Teleported successfully!");
    
        Reset(msg);
        Reset(target);
        }
    }   
    
  5. В Project_B скопируйте следующий код в Main.qs

    
        operation Teleport(msg : Qubit, target : Qubit) : Unit {
            use here = Qubit();
    
            PrepareBellPair(here, target); 
            Adjoint PrepareBellPair(msg, here);
    
            if M(msg) == One { Z(target); }
            if M(here) == One { X(target); }
    
            Reset(here);
        }
    
        operation PrepareBellPair(left : Qubit, right : Qubit) : Unit is Adj + Ctl {
            H(left);
            CNOT(left, right);
        }
    
        export Teleport;       //  makes the Teleport operation available to external programs
    

    Примечание.

    Обратите внимание, что PrepareBellPair операция не требуется экспортировать, так как она не вызывается непосредственно из программы в Project_A. Так как он находится в локальной области Project_B, он уже доступен операцией Teleport .

  6. Чтобы запустить программу, откройте /Project_A/Main.qs в VS Code и выберите "Выполнить".

Проекты и неявные пространства имен

В Q# проектах, если пространство имен не указано в программе *.qs, компилятор использует имя файла в качестве пространства имен. Ссылка на вызываемую из внешней зависимости затем использует синтаксис <dependencyName>.<пространство> имен.<вызывающий объект>. Однако если файл называется Main.qs, компилятор предполагает пространство имен и синтаксис вызова — <dependencyName>.<вызывающий объект>, как в предыдущем примере. import MyTeleportLib.Teleport

Так как у вас не редкость несколько файлов проекта, необходимо учитывать правильный синтаксис при ссылке на вызываемые файлы. Например, в проекте со следующей структурой файлов

  • /src
    • Main.qs
    • MathFunctions.qs

вызовы внешней зависимости будут

import MyTeleportLib.MyFunction;        // "Main" namespace is implied

import MyTeleportLib.MathFunctions.MyFunction;   // "Math" namespace must be explicit 

Дополнительные сведения о поведении пространства имен см. в разделе "Пространства имен пользователей".