Azure Quantum Jobs client library for .NET - version 1.0.0-beta.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:

Getting started

This section should include everything a developer needs to do to install and create their first client connection very quickly.

Install the package

Install the Azure Quantum Jobs client library for .NET with NuGet:

dotnet add package Azure.Quantum.Jobs --prerelease -v 1.0.0-beta.1

Prerequisites

Include a section after the install command that details any requirements that must be satisfied before a developer can authenticate and test all of the snippets in the Examples section. For example, for Cosmos DB:

You must have an Azure subscription, Cosmos DB account (SQL API), and Python 3.6+ to use this package.

Authenticate the client

To authenticate with the service, the workspace will use DefaultAzureCredential internally. This will try different authentication mechanisms based on the environment (e.g. Environment Variables, ManagedIdentity, CachedTokens) and finally it will fallback to InteractiveBrowserCredential.

Workspace will also allow the user to override the above behavior by passing their own TokenCredential.

TokenCredential is the default Authentication mechanism used by Azure SDKs.

Key concepts

QuantumJobClient is the root class to be used to authenticate and create, enumerate, and cancel jobs.

JobDetails contains all the properties of a job.

ProviderStatus contains status information for a provider.

QuantumJobQuota contains quota properties.

Thread safety

We guarantee that all client instance methods are thread-safe and independent of each other (guideline). This ensures that the recommendation of reusing client instances is always safe, even across threads.

Additional concepts

Client options | Accessing the response | Long-running operations | Handling failures | Diagnostics | Mocking | Client lifetime

Examples

Create the client

Create an instance of the QuantumJobClient by passing in these parameters:

  • Subscription - looks like XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX and can be found in your list of subscriptions on azure
  • Resource Group - a container that holds related resources for an Azure solution
  • Workspace - a collection of assets associated with running quantum or optimization applications
  • Location - choose the best data center by geographical region
  • StorageContainerName - your blob storage
  • Credential - used to authenticate
// Create a QuantumJobClient
var subscriptionId = "your_subscription_id";
var resourceGroupName = "your_resource_group_name";
var workspaceName = "your_quantum_workspace_name";
var location = "your_location";
var storageContainerName = "your_container_name";

var credential = new DefaultAzureCredential(true);

var quantumJobClient =
    new QuantumJobClient(
        subscriptionId,
        resourceGroupName,
        workspaceName,
        location,
        credential);

Get Container SAS URI

Create a storage container where to put your data.

// Get container Uri with SAS key
var containerUri = (quantumJobClient.GetStorageSasUri(
    new BlobDetails(storageContainerName))).Value.SasUri;

Upload Input Data

Using the SAS URI, upload the compressed json input data to the blob client. Note that we need to compress the json input data before uploading it to the blob storage. This contains the parameters to be used with Quantum Inspired Optimizations

string problemFilePath = "./problem.json";

// Get input data blob Uri with SAS key
string blobName = Path.GetFileName(problemFilePath);
var inputDataUri = (quantumJobClient.GetStorageSasUri(
    new BlobDetails(storageContainerName)
    {
        BlobName = blobName,
    })).Value.SasUri;

using (var problemStreamToUpload = new MemoryStream())
{
    using (FileStream problemFileStream = File.OpenRead(problemFilePath))
    {
        // Check if problem file is a gzip file.
        // If it is, just read its contents.
        // If not, read and compress the content.
        var fileExtension = Path.GetExtension(problemFilePath).ToLower();
        if (fileExtension == ".gz" ||
            fileExtension == ".gzip")
        {
            problemFileStream.CopyTo(problemStreamToUpload);
        }
        else
        {
            using (var gzip = new GZipStream(problemStreamToUpload, CompressionMode.Compress, leaveOpen: true))
            {
                byte[] buffer = new byte[8192];
                int count;
                while ((count = problemFileStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    gzip.Write(buffer, 0, count);
                }
            }
        }
    }
    problemStreamToUpload.Position = 0;

    // Upload input data to blob
    var blobClient = new BlobClient(new Uri(inputDataUri));
    var blobHeaders = new BlobHttpHeaders
    {
        ContentType = "application/json",
        ContentEncoding = "gzip"
    };
    var blobUploadOptions = new BlobUploadOptions { HttpHeaders = blobHeaders };
    blobClient.Upload(problemStreamToUpload, options: blobUploadOptions);
}

Create The Job

Now that you've uploaded your problem definition to Azure Storage, you can use CreateJob to define an Azure Quantum job.

// Submit job
var jobId = $"job-{Guid.NewGuid():N}";
var jobName = $"jobName-{Guid.NewGuid():N}";
var inputDataFormat = "microsoft.qio.v2";
var outputDataFormat = "microsoft.qio-results.v2";
var providerId = "microsoft";
var target = "microsoft.paralleltempering-parameterfree.cpu";
var inputParams = new Dictionary<string, object>() { { "params", new Dictionary<string, object>() } };
var createJobDetails = new JobDetails(containerUri, inputDataFormat, providerId, target)
{
    Id = jobId,
    InputDataUri = inputDataUri,
    Name = jobName,
    InputParams = inputParams,
    OutputDataFormat = outputDataFormat
};

JobDetails myJob = (quantumJobClient.CreateJob(jobId, createJobDetails)).Value;

Get Job

GetJob retrieves a specific job by its id.

// Get the job that we've just created based on its jobId
myJob = (quantumJobClient.GetJob(jobId)).Value;

Get Jobs

To enumerate all the jobs in the workspace, use the GetJobs method.

foreach (JobDetails job in quantumJobClient.GetJobs())
{
   Console.WriteLine($"{job.Name}");
}

Troubleshooting

All Quantum Jobs service operations will throw a RequestFailedException on failure with helpful ErrorCodes. Many of these errors are recoverable.

Next steps

Contributing

See the CONTRIBUTING.md for details on building, testing, and contributing to this library.

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

Impressions