|
1 | 1 | # Azure Quantum Jobs client library for .NET |
2 | 2 |
|
3 | | -Azure Quantum is a Microsoft Azure service that you can use to run quantum computing programs or solve optimization problems in the cloud. Using the Azure Quantum tools and SDKs, you can create quantum programs and run them against different quantum simulators and machines. You can use the Azure.Quantum.Jobs client library to: |
| 3 | +Azure Quantum is a Microsoft Azure service that you can use to run quantum computing programs in the cloud. Using the Azure Quantum tools and SDKs, you can create quantum programs and run them against different quantum simulators and machines. You can use the Azure.Quantum.Jobs client library to: |
4 | 4 | - Create, enumerate, and cancel quantum jobs |
5 | 5 | - Enumerate provider status and quotas |
6 | 6 |
|
@@ -69,7 +69,7 @@ We guarantee that all client instance methods are thread-safe and independent of |
69 | 69 | Create an instance of the QuantumJobClient by passing in these parameters: |
70 | 70 | - [Subscription][subscriptions] - looks like XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX and can be found in your list of subscriptions on azure |
71 | 71 | - [Resource Group][resource-groups] - a container that holds related resources for an Azure solution |
72 | | -- [Workspace][workspaces] - a collection of assets associated with running quantum or optimization applications |
| 72 | +- [Workspace][workspaces] - a collection of assets associated with running quantum |
73 | 73 | - [Location][location] - choose the best data center by geographical region |
74 | 74 | - [StorageContainerName][blob-storage] - your blob storage |
75 | 75 | - [Credential][credentials] - used to authenticate |
@@ -103,76 +103,67 @@ var containerUri = (quantumJobClient.GetStorageSasUri( |
103 | 103 | new BlobDetails(storageContainerName))).Value.SasUri; |
104 | 104 | ``` |
105 | 105 |
|
| 106 | +### Compile your quantum program into QIR |
| 107 | + |
| 108 | +This step can be done in multiple ways and it is not in scope for this sample. |
| 109 | + |
| 110 | +[Quantum Intermediate Representation (QIR)](https://github.com/qir-alliance/qir-spec) is a [QIR Alliance](https://www.qir-alliance.org/) specification to represent quantum programs within the [LLVM](https://llvm.org/) Intermediate Representation (IR). |
| 111 | + |
| 112 | +A few methods to compile or generate a quantum program into QIR: |
| 113 | +- [Q# compiler](https://github.com/microsoft/qsharp-compiler/): Can be used to [compile Q# Code into QIR](https://github.com/microsoft/qsharp-compiler/tree/main/src/QsCompiler/QirGeneration). |
| 114 | +- [PyQIR](https://github.com/qir-alliance/pyqir): PyQIR is a set of APIs for generating, parsing, and evaluating Quantum Intermediate Representation (QIR). |
| 115 | +- [IQ#](https://github.com/microsoft/iqsharp): Can be used to compile a Q# program into QIR with the [%qir](https://learn.microsoft.com/qsharp/api/iqsharp-magic/qir) magic command. |
| 116 | + |
| 117 | +In this sample, we assume you already have a file with the QIR bitcode and you know the method name that you want to execute (entry point). |
| 118 | + |
| 119 | +We will use the QIR bitcode sample (./samples/BellState.bc), compiled a Q# code (./samples/BellState.qs) targeting the `quantinuum.sim.h1-1e` target, with `AdaptiveExecution` target capability. |
| 120 | + |
106 | 121 | ### Upload Input Data |
107 | 122 |
|
108 | | -Using the SAS URI, upload the compressed json input data to the blob client. |
109 | | -Note that we need to compress the json input data before uploading it to the blob storage. |
110 | | -This contains the parameters to be used with [Quantum Inspired Optimizations](https://docs.microsoft.com/azure/quantum/optimization-overview-introduction) |
| 123 | +Using the SAS URI, upload the QIR bitcode input data to the blob client. |
111 | 124 |
|
112 | | -```C# Snippet:Azure_Quantum_Jobs_UploadInputData |
113 | | -string problemFilePath = "./problem.json"; |
| 125 | +```C# Snippet:Azure_Quantum_Jobs_UploadQIRBitCode |
| 126 | +string qirFilePath = "./BellState.bc"; |
114 | 127 |
|
115 | 128 | // Get input data blob Uri with SAS key |
116 | | -string blobName = Path.GetFileName(problemFilePath); |
| 129 | +string blobName = Path.GetFileName(qirFilePath); |
117 | 130 | var inputDataUri = (quantumJobClient.GetStorageSasUri( |
118 | 131 | new BlobDetails(storageContainerName) |
119 | 132 | { |
120 | 133 | BlobName = blobName, |
121 | 134 | })).Value.SasUri; |
122 | 135 |
|
123 | | -using (var problemStreamToUpload = new MemoryStream()) |
| 136 | +// Upload QIR bitcode to blob storage |
| 137 | +var blobClient = new BlobClient(new Uri(inputDataUri)); |
| 138 | +var blobHeaders = new BlobHttpHeaders |
124 | 139 | { |
125 | | - using (FileStream problemFileStream = File.OpenRead(problemFilePath)) |
126 | | - { |
127 | | - // Check if problem file is a gzip file. |
128 | | - // If it is, just read its contents. |
129 | | - // If not, read and compress the content. |
130 | | - var fileExtension = Path.GetExtension(problemFilePath).ToLower(); |
131 | | - if (fileExtension == ".gz" || |
132 | | - fileExtension == ".gzip") |
133 | | - { |
134 | | - problemFileStream.CopyTo(problemStreamToUpload); |
135 | | - } |
136 | | - else |
137 | | - { |
138 | | - using (var gzip = new GZipStream(problemStreamToUpload, CompressionMode.Compress, leaveOpen: true)) |
139 | | - { |
140 | | - byte[] buffer = new byte[8192]; |
141 | | - int count; |
142 | | - while ((count = problemFileStream.Read(buffer, 0, buffer.Length)) > 0) |
143 | | - { |
144 | | - gzip.Write(buffer, 0, count); |
145 | | - } |
146 | | - } |
147 | | - } |
148 | | - } |
149 | | - problemStreamToUpload.Position = 0; |
150 | | - |
151 | | - // Upload input data to blob |
152 | | - var blobClient = new BlobClient(new Uri(inputDataUri)); |
153 | | - var blobHeaders = new BlobHttpHeaders |
154 | | - { |
155 | | - ContentType = "application/json", |
156 | | - ContentEncoding = "gzip" |
157 | | - }; |
158 | | - var blobUploadOptions = new BlobUploadOptions { HttpHeaders = blobHeaders }; |
159 | | - blobClient.Upload(problemStreamToUpload, options: blobUploadOptions); |
| 140 | + ContentType = "qir.v1" |
| 141 | +}; |
| 142 | +var blobUploadOptions = new BlobUploadOptions { HttpHeaders = blobHeaders }; |
| 143 | +using (FileStream qirFileStream = File.OpenRead(qirFilePath)) |
| 144 | +{ |
| 145 | + blobClient.Upload(qirFileStream, options: blobUploadOptions); |
160 | 146 | } |
161 | 147 | ``` |
162 | 148 |
|
163 | 149 | ### Create The Job |
164 | 150 |
|
165 | | -Now that you've uploaded your problem definition to Azure Storage, you can use `CreateJob` to define an Azure Quantum job. |
| 151 | +Now that you've uploaded your QIR program bitcode to Azure Storage, you can use `CreateJob` to define an Azure Quantum job. |
166 | 152 |
|
167 | 153 | ```C# Snippet:Azure_Quantum_Jobs_CreateJob |
168 | 154 | // Submit job |
169 | 155 | var jobId = $"job-{Guid.NewGuid():N}"; |
170 | 156 | var jobName = $"jobName-{Guid.NewGuid():N}"; |
171 | | -var inputDataFormat = "microsoft.qio.v2"; |
172 | | -var outputDataFormat = "microsoft.qio-results.v2"; |
173 | | -var providerId = "microsoft"; |
174 | | -var target = "microsoft.paralleltempering-parameterfree.cpu"; |
175 | | -var inputParams = new Dictionary<string, object>() { { "params", new Dictionary<string, object>() } }; |
| 157 | +var inputDataFormat = "qir.v1"; |
| 158 | +var outputDataFormat = "microsoft.quantum-results.v1"; |
| 159 | +var providerId = "quantinuum"; |
| 160 | +var target = "quantinuum.sim.h1-1e"; |
| 161 | +var inputParams = new Dictionary<string, object>() |
| 162 | +{ |
| 163 | + { "entryPoint", "ENTRYPOINT__BellState" }, |
| 164 | + { "arguments", new string[] { } }, |
| 165 | + { "targetCapability", "AdaptiveExecution" }, |
| 166 | +}; |
176 | 167 | var createJobDetails = new JobDetails(containerUri, inputDataFormat, providerId, target) |
177 | 168 | { |
178 | 169 | Id = jobId, |
|
0 commit comments