Создание проектов и пользовательских библиотек и управление ими Q#
В этой статье вы узнаете, как создавать, управлять и совместно использовать Q# проекты. Q# проекты — это структуры папок с несколькими Q# файлами, которые могут получить доступ к операциям и функциям друг друга. Проекты полезны для логического упорядочения исходного кода. Вы также можете использовать проекты в качестве пользовательских библиотек, к которым можно получить доступ из внешних источников.
Необходимые компоненты
- Рабочая область Azure Quantum по подписке Azure. Сведения о создании рабочей области см. в статье Создание рабочей области Azure Quantum.
- Visual Studio Code с установленным расширением Azure Quantum Development Kit и Python .
- Учетная запись GitHub, если вы планируете опубликовать внешний проект в общедоступном репозитории GitHub.
Для запуска программ Python также требуется:
- Среда Python с установленным Python и Pip .
- Azure Quantum
qsharp
иazure-quantum
пакеты.
Как 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# программы)
При открытии файла *.qs в VS Code Q# компилятор выполняет поиск вверх в структуре папок для файла манифеста. Если он находит файл манифеста, компилятор будет содержать все Q# файлы в каталоге /src или любой из его подкаталогов. Элементы каждого файла становятся доступными для всех остальных файлов в проекте.
Например, учитывая эту структуру папок:
- Teleportation_project
- qsharp.json
- src
- Main.qs
- TeleportOperations
- TeleportLib.qs
- PrepareState
- PrepareStateLib.qs
При открытии файла /src/TeleportOperation/PrepareState/PrepareStateLib.qsQ# компилятор:
- Проверяет /src/TeleportOperation/PrepareState/ для qsharp.json.
- Проверяет значение /src/TeleportOperation для qsharp.json.
- Проверяет /src для qsharp.json.
- Проверяет / наличие qsharp.json.
- / Устанавливает в качестве корневого каталога проекта и включает все файлы *.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# проектам.
В проводнике VS Code щелкните правой кнопкой мыши папку, которую вы хотите использовать для корневой Q# папки проекта, и выберите "Создать Q# проект" или откройте папку и выберите команду View > Command Palette >Q#: Create a Q# project....
VS Code создает минимальный файл манифеста в папке и добавляет
/src
папку с файломMain.qs
шаблона.Измените файл манифеста по мере необходимости. См . примеры файлов манифеста.
Добавьте и упорядочение Q# исходных файлов в папке
/src
.Если вы обращаетесь к Q# проекту из программы Python или Jupyter Notebook, задайте путь к корневой папке с помощью
qsharp.init
. В этом примере предполагается, что программа находится в папке Q# /src проекта:qsharp.init(project_root = '../Teleportation_project')
Если вы используете только 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.*;
.
Пример внешнего проекта
В этом примере вы будете использовать ту же программу телепортации, что и предыдущий пример, но отделяйте вызывающую программу и вызываемые элементы в разных проектах.
Создайте две папки на локальном диске, например "Project_A" и "Project_B".
Создайте проект в каждой Q# папке, выполнив действия, описанные в разделе "Действия по созданию Q# проекта".
В Project_A вызываемая программа скопируйте следующий код в файл манифеста, изменив путь по мере необходимости для Project_B
{ "author": "Microsoft", "license": "MIT", "dependencies": { "MyTeleportLib": { "path": "/Project_B" } } }
В 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); } }
В 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
.Чтобы запустить программу, откройте /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
Дополнительные сведения о поведении пространства имен см. в разделе "Пространства имен пользователей".