Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
In this article, you learn how to create, manage, and share Q# projects. A Q# project is a folder structure with multiple Q# files that can access each other's operations and functions. Projects help you logically organize your source code. You can also use projects as custom libraries that can be accessed from external sources.
Prerequisites
- An Azure Quantum workspace in your Azure subscription. To create a workspace, see Create an Azure Quantum workspace.
- Visual Studio Code (VS Code) with the Azure Quantum Development Kit and Python extension installed.
- A GitHub account, if you plan to publish your external project to a public GitHub repository.
To run Python programs, you also need:
- A Python environment with Python and Pip installed.
- The Azure Quantum
qsharpandazure-quantumpackages.
How Q# projects work
A Q# project contains a Q# manifest file, named qsharp.json, and one or more .qs files in a specified folder structure. You can create a Q# project manually or directly in VS Code.
When you open a .qs file in VS Code, the compiler searches the surrounding folder hierarchy for the manifest file and determines the project's scope. If no manifest file is found, then the compiler operates in a single file mode.
When you set the project_root in a Jupyter Notebook or Python file, the compiler looks for the manifest file in the project_root folder.
An external Q# project is a standard Q# project that resides in another directory or on a public GitHub repository, and acts as a custom library. An external project uses export statements to define the functions and operations that are accessible by external programs. Programs define the external project as a dependency in their manifest file, and use import statements to access the items in the external project, such as operations, functions, structs, and namespaces. For more information, see Using projects as external dependencies.
Define a Q# project
A Q# project is defined by the presence of a manifest file, named qsharp.json, and a src folder, both of which must be in the root folder of the project. The src folder contains the Q# source files. For Q# programs and external projects, the Q# compiler detects the project folder automatically. For Python programs and Jupyter Notebook files, you must specify the Q# project folder with a qsharp.init call. However, the folder structure for a Q# project is the same for all types of programs.
Define the project folder (Q# programs)
When you open a .qs file in VS Code, the Q# compiler searches upward in the folder structure for a manifest file. If the compiler finds a manifest file, then the compiler includes all Q# files in the /src directory and all of it subdirectories. The items defined in each file become available to all other files within the project.
For example, consider the following folder structure:
- Teleportation_project
- qsharp.json
- src
- Main.qs
- TeleportOperations
- TeleportLib.qs
- PrepareState
- PrepareStateLib.qs
When you open the file /src/TeleportOperation/PrepareState/PrepareStateLib.qs, the Q# compiler does the following:
- Checks
/src/TeleportOperation/PrepareState/forqsharp.json. - Checks
/src/TeleportOperationforqsharp.json. - Checks
/srcforqsharp.json. - Checks
/*forqsharp.json. - Establishes
/as the root directory of the project, and includes all.qsfiles under the root in the project, per the manifest file's settings.
Create a manifest file
A manifest file is a JSON file named qsharp.json that can optionally include author, license, and lints fields. The minimum viable manifest file is the string {}. When you create a Q# project in VS Code, a minimal manifest file is created for you.
{}
Manifest file examples
The following examples show how manifest files can define the scope of your Q# project.
In this example, author is the only specified field, so all
.qsfiles in this directory and its subdirectories are included in the Q# project.{ "author":"Microsoft", "license": "MIT" }Within a Q# project, you can also use the manifest file to fine-tune the VS Code Q# Linter settings. By default, the three Linter rules are:
needlessParens: default =allowdivisionByZero: default =warnredundantSemicolons: default =warnYou can set each rule in the manifest file to either
allow,warn, orerror. For example:{ "author":"Microsoft", "lints": [ { "lint": "needlessParens", "level": "allow" }, { "lint": "redundantSemicolons", "level": "warn" }, { "lint": "divisionByZero", "level": "error" } ] }
You can also use the manifest file to define an external Q# project as a dependency and remotely access operations and functions in that external project. For more information, see Using projects as external dependencies.
Q# project requirements and properties
The following requirements and configurations apply to all Q# projects.
All
.qsfiles that you want to include in the project must be under a folder namedsrc, which must be under the root folder of the Q# project. When you create a Q# project in VS Code, the/srcfolder is automatically created.The manifest file should be at the same level as the
srcfolder. When you create a Q# project in VS Code, a minimal file is created automatically.Use
importstatements to reference operations and functions from other files in the project.import MyMathLib.*; //imports all the callables in the MyMathLib namespace ... Multiply(x,y);Or, reference them individually with the namespace.
MyMathLib.Multiply(x,y);
For Q# projects only
- You can define an entry point operation in only one
.qsfile in a Q# project, which is theMain()operation by default. - You must put the
.qsfile with the entry point definition at a project directory level below the manifest file. - All operations and functions in the Q# project that are cached from a
.qsdisplay in predictive text in VS Code. - If the namespace for a selected operation or function isn't imported yet, then VS Code automatically adds the necessary
importstatement.
How to create a Q# project
To create a Q# project, follow these steps:
In the VS Code file explorer, go to the folder that you want to use as the root folder for the Q# project.
Open the View menu and choose Command Palette.
Enter QDK: Create Q# project and press Enter. VS Code creates a minimal manifest file in the folder, and adds a
/srcfolder with aMain.qstemplate file.Edit the manifest file for your project. See Manifest file examples.
Add and organize your Q# source files under the
/srcfolder.If you're accessing the Q# project from a Python program or Jupyter Notebook, set the root folder path using
qsharp.init. This example assumes that your program is in the/srcfolder of the Q# project:qsharp.init(project_root = '../Teleportation_project')If you're using only Q# files in VS Code, then the compiler searches for a manifest file when you open a Q# file, determines the root folder of the project, and then scans the subfolder for
.qsfiles.
Note
You can also manually create the manifest file and the /src folder.
Example project
This quantum teleportation program is an example of a Q# project that runs on the local simulator in VS Code. To run the program on Azure Quantum hardware or third-party simulators, see Get started with Q# programs and VS Code for steps to compile your program and connect to your Azure Quantum workspace.
This example has the following directory structure:
- Teleportation_project
- qsharp.json
- src
- Main.qs
- TeleportOperations
- TeleportLib.qs
- PrepareState
- PrepareStateLib.qs
The manifest file contains the author and license fields:
{
"author":"Microsoft",
"license":"MIT"
}
Q# source files
The main file, named Main.qs, contains the entry point and references the TeleportOperations.TeleportLib namespace from 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);
}
}
The TeleportLib.qs files defines the Teleport operation and calls the PrepareBellPair operation from the PrepareStateLib.qs file.
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);
}
The PrepareStateLib.qs file contains a standard reusable operation to create a Bell pair.
operation PrepareBellPair(left : Qubit, right : Qubit) : Unit is Adj + Ctl {
H(left);
CNOT(left, right);
}
Run the programs
Choose the tab for the environment that you run your program in.
To run this program, open the Main.qs file in VS Code and choose Run.
Configure Q# projects as external dependencies
You can configure Q# projects as an external dependencies for other projects, similar to a library. The functions and operations in the external Q# project are made available to multiple Q# projects. An external dependency can reside on a drive share or be published to a public GitHub repository.
To use a Q# project as an external dependency, you must:
- Add the external project as a dependency in the manifest file of the calling project.
- If the external project is published to GitHub, then add the files property to the manifest file of the external project.
- Add
exportstatements to the external project. - Add
importstatements to the calling project.
Configure the manifest files
External Q# projects can reside on a local or network drive share, or be published to a public GitHub repository.
The calling project manifest file
To add a dependency to an external project on a drive share, define the dependency in the manifest file of the calling project.
{
"author": "Microsoft",
"license": "MIT",
"dependencies": {
"MyDependency": {
"path": "/path/to/project/folder/on/disk"
}
}
}
In the preceding manifest file, MyDependency is a user defined string that identifies the namespace when you call an operation. For example, if you create a dependency named MyMathFunctions, then you can call a function from that dependency with MyMathFunctions.MyFunction().
To add a dependency to a project that's published to a public GitHub repository, use the following example manifest file:
{
"author": "Microsoft",
"dependencies": {
"MyDependency": {
"github": {
"owner": "GitHubUser",
"repo": "GitHubRepoName",
"ref": "CommitHash",
"path": "/path/to/dependency"
}
}
}
}
Note
For GitHub dependencies, ref refers to a GitHub refspec. Microsoft recommends that you always use a commit hash so that you can rely on a specific version of your dependency.
The external project manifest file
If your external Q# project is published to a public GitHub repository, then you must add the files property to the manifest file of the external project, including all files used in the project.
{
"author": "Microsoft",
"license": "MIT",
"files": [ "src/MyMathFunctions.qs", "src/Strings/MyStringFunctions.qs" ]
}
The files property is optional for an external project that's imported via "path" (that is, a local filepath-based import). The files property is required only for projects that are published to GitHub.
Use the export statement
To make functions and operations in an external project accessible to calling projects, use the export statement. You can export any or all of the callables in the file. Wild card syntax isn't supported, so you must specify each callable that you want to 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;
Use the import statement
To make items from an external dependency available, use import statements from the calling program. The import statement uses the namespace that's defined for the dependency in the manifest file.
For example, consider the dependency in the following manifest file:
{
"author": "Microsoft",
"license": "MIT",
"dependencies": {
"MyMathFunctions": {
"path": "/path/to/project/folder/on/disk"
}
}
}
Import the callables with the following code:
import MyMathFunctions.MyFunction; // imports "MyFunction()" from the namespace
...
The import statement also supports wild card syntax and aliases.
// 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;
Note
The currently used open statement in Q#, which is used to reference libraries and namespaces, is still supported but will be deprecated eventually. In the meantime, you can optionally update your current files to use the import statement. For example, open Std.Diagnostics; can be replaced with import Std.Diagnostics.*;.
Example external project
For this example, you'll use the same teleportation program as the earlier example, but separate the calling program and the callables into different projects.
Create two folders on your local drive, for example "Project_A" and "Project_B".
Create a Q# project in each folder following the steps in How to create a Q# project.
In Project_A, the calling program, copy the following code into the manifest file, editing the path as needed for Project_B
{ "author": "Microsoft", "license": "MIT", "dependencies": { "MyTeleportLib": { "path": "/Project_B" } } }In Project_A, copy the following code into 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); } }In Project_B, copy the following code into 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 programsNote
Note that the
PrepareBellPairoperation does not need to be exported because it is not called directly from your program in Project_A. Because it is in the local scope of Project_B, it is already accessible by theTeleportoperationTo run the program, open
/Project_A/Main.qsin VS Code and choose Run.
Projects and implicit namespaces
In Q# projects, if a namespace is not specified in a .qs program, then the compiler uses the file name as the namespace. Referencing a callable from an external dependency then uses the syntax <dependencyName>.<namespace>.<callable>. However, if the file is named Main.qs, then the compiler assumes the namespace and the calling syntax is <dependencyName>.<callable>, as in the previous example, import MyTeleportLib.Teleport.
Because you might have multiple project files, you need to account for the correct syntax when your reference callables. For example, consider a project with the following file structure:
- /src
- Main.qs
- MathFunctions.qs
The following code makes calls to the external dependency:
import MyTeleportLib.MyFunction; // "Main" namespace is implied
import MyTeleportLib.MathFunctions.MyFunction; // "Math" namespace must be explicit
For more information about namespace behavior, see User namespaces.