Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.

Conversation

@rmshaffer
Copy link
Contributor

@rmshaffer rmshaffer commented Jun 3, 2020

This PR contains the code to auto-generate an @EntryPoint() operation for Azure Quantum job submission from IQ#. This operation then gets compiled into a separate executable assembly that references the Workspace and Snippets assemblies.

The key places to start reviewing would be:

  • new function BuildEntryPoint() in src/Core/Compiler/CompilerService.cs
  • new class EntryPointGenerator in src/AzureClient/EntryPoint/EntryPointGenerator.cs
  • new class EntryPoint in src/AzureClient/EntryPoint/EntryPoint.cs
  • consuming function SubmitOrExecuteJobAsync() in src/AzureClient/AzureClient.cs

Fixes AB#13591, fixes AB#15418.

rmshaffer and others added 30 commits May 28, 2020 18:03
Co-authored-by: Chris Granade <chgranad@microsoft.com>
@rmshaffer rmshaffer marked this pull request as ready for review June 5, 2020 15:04
@rmshaffer rmshaffer requested a review from anpaz June 5, 2020 20:24
Base automatically changed from rmshaffer/azure-targets to feature/azure-client June 8, 2020 14:02
Comment on lines +62 to +66
var decodedParameters = new Dictionary<string, string>();
foreach (var key in inputParameters.Keys)
{
decodedParameters[key] = inputParameters.DecodeParameter<string>(key);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
var decodedParameters = new Dictionary<string, string>();
foreach (var key in inputParameters.Keys)
{
decodedParameters[key] = inputParameters.DecodeParameter<string>(key);
}
var decodedParameters = inputParameters.ToDictionary(
item => inputParameters.DecodeParameter<string>(item.Key),
item => item.Value);

This is an optional suggestion. :) Just wanted to throw the LINQ version out there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great, I always prefer LINQ, thanks for pointing this out! I'm going to apply this change in one of my other PRs since I've already started refactoring this a bit on another branch.

{{
return {operation.Header.QualifiedName}{argumentTuple};
}}
}}";
Copy link
Contributor

@bamarsha bamarsha Jun 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of compiling this string, is it possible to attach the EntryPoint attribute to the callable in the compiled Q# syntax tree, maybe as a rewrite step? Not sure if there are any issues with that way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had some discussions about this with @bettinaheim and @anpaz-msft. The reason I ended up doing it this way is that we want to ignore any @EntryPoint() attributes that happen to appear inside snippets (code from notebook cells), and we are doing this by compiling the snippets as a library and suppressing the resulting warning.

If we want to attach the @EntryPoint() attribute directly to the operation in the snippet code and compile the snippets as an executable, then we'd have to also go remove the attribute from any other snippet operations where it might exist. I think this is certainly possible by manipulating the syntax tree, as you suggest, and maybe we can change to go that route in the future if needed, but this seemed like the simplest solution at the moment.

One potential benefit of this approach is that in the future it may be possible to reference other Q# projects from IQ#, including Q# library projects. This approach would also give a way to submit those operations to Azure Quantum without having to manually create a wrapper operation in the notebook.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems reasonable, I agree that this is probably simpler. Thanks for explaining!

One potential benefit of this approach is that in the future it may be possible to reference other Q# projects from IQ#, including Q# library projects. This approach would also give a way to submit those operations to Azure Quantum without having to manually create a wrapper operation in the notebook.

I haven't tested it, but you could probably still attach the entry point attribute to callables in a reference. I think they all get added to the same syntax tree.

Copy link
Contributor

@cgranade cgranade left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few minor suggestions, thanks!

var timeoutInSeconds = 30;
channel.Stdout($"Waiting up to {timeoutInSeconds} seconds for Azure Quantum job to complete...");

using (var cts = new System.Threading.CancellationTokenSource(TimeSpan.FromSeconds(30)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this timeout be configurable? That may be doable with the %config magic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! In fact I have made it configurable in #161.

{
// TODO: Once jupyter-core supports interrupt requests (https://github.com/microsoft/jupyter-core/issues/55),
// handle Jupyter kernel interrupt here and break out of this loop
var pollingIntervalInSeconds = 5;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same, this is configurable in #161. Reading my mind...

Ryan Shaffer and others added 3 commits June 10, 2020 19:52
Co-authored-by: Chris Granade <chgranad@microsoft.com>
Co-authored-by: Chris Granade <chgranad@microsoft.com>
@rmshaffer
Copy link
Contributor Author

Thanks @ricardo-espinoza @SamarSha @cgranade for the detailed review and feedback! I think I've responded to all of the comments, but please let me know if I've missed something. When you have a chance, please let me know whether you have any additional concerns/feedback, or whether you're comfortable approving these changes.


// Find and invoke the method on IQuantumMachine that is declared as:
// Task<IQuantumMachineJob> SubmitAsync<TInput, TOutput>(EntryPointInfo<TInput, TOutput> info, TInput input)
var submitMethod = typeof(IQuantumMachine)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following up offline with @rmshaffer on this. Requiring reflection to find the method to call might be needed, but we should discuss ways to avoid it. An option could be to find an abstraction that could encapsulate input/output in some sort of composition type so the IQuantumMachine method could be generic and could be found without searching through the assembly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Closing the loop here. No objections with keeping it as it is, but it's something we could discuss in the future in terms of the design of the interface itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, thanks @ricardo-espinoza! One minor note for additional context is that the IQuantumMachine interface is defined in the qsharp-runtime repo and is also used by the Q# standalone executable framework, which uses generated code to call these methods and so doesn't require reflection. The strong type safety is nice in that case.

@rmshaffer rmshaffer merged commit 1c17687 into feature/azure-client Jun 12, 2020
@rmshaffer rmshaffer deleted the rmshaffer/azure-entrypoint branch June 12, 2020 19:31
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants