銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

Q#プロジェクトでC#のクラスが不要になりました

しばらくQ#の記事を書いていなかったのですが、最近のQ#の更新でC#のクラスが不要になっていたので久しぶりに記事を書きたいと思います。

少し古い記事ですが、Q#プロジェクトというのは、プロジェクトとしては.NET Coreのプロジェクトで、エントリポイントとなるMainメソッドを含むC#クラスが存在し、そこから呼び出されるQ#のソースが存在する構造でした。

tech.tanaka733.net

ですが、今年4月にリリースされたVersion 0.11.2004.2825からこのC#クラスが不要になりました。

例えば最新のQ# SDKでプロジェクトを作るとこのような構造のProgram.qsファイルとcsprojファイルのみのプロジェクトが作られます。

namespace Quantum.QSharpCompilerExtensionLab {

    open Microsoft.Quantum.Canon;
    open Microsoft.Quantum.Intrinsic;

    
    @EntryPoint()
    operation HelloQ () : Unit {
        Message("Hello quantum world!");
    }
}

この@EntryPoint()というのがC#のMainメソッドに相当するものになります。これがどのように動くのかが気になるので、コンパイル(トランスパイル)結果を見てみましょう。最新のバージョンでもQ#コードはいったんC#にトランスパイルされてからコンパイルされます。C#としての出力は、/obj/qsharp/src以下にあります。

f:id:tanaka733:20200607212741p:plain

このProgram.g.csのほうが以前と同じQ#コードをC#コードにトランスパイルしたもののようです。もう一つのProgram.EntryPoint.g.csのほうがMainメソッドを含むエントリーポイントのためのコンパイル結果です。実際にはこのようになっています。

//------------------------------------------------------------------------------
// <auto-generated>                                                             
//     This code was generated by a tool.                                       
//     Changes to this file may cause incorrect behavior and will be lost if    
//     the code is regenerated.                                                 
// </auto-generated>                                                            
//------------------------------------------------------------------------------
namespace Quantum.QSharpCompilerExtensionLab
{
    using System;
    using Microsoft.Quantum.Core;
    using Microsoft.Quantum.Intrinsic;
    using Microsoft.Quantum.Simulation.Core;

    internal class __QsEntryPoint__ : Microsoft.Quantum.CsharpGeneration.EntryPointDriver.IEntryPoint<QVoid, QVoid>
    {
        public string Summary => "";
        public System.Collections.Generic.IEnumerable<System.CommandLine.Option> Options => new System.CommandLine.Option[] { };
        public string DefaultSimulator => "QuantumSimulator";
        public EntryPointInfo<QVoid, QVoid> Info => Quantum.QSharpCompilerExtensionLab.HelloQ.Info;
        public IOperationFactory CreateDefaultCustomSimulator() => throw new InvalidOperationException();
        public QVoid CreateArgument(System.CommandLine.Parsing.ParseResult parseResult) => QVoid.Instance;
        private static async System.Threading.Tasks.Task<int> Main(string[] args) => await new Microsoft.Quantum.CsharpGeneration.EntryPointDriver.Driver<Quantum.QSharpCompilerExtensionLab.HelloQ, QVoid, QVoid>(new __QsEntryPoint__()).Run(args);
    }
}

MainメソッドはDriver.Runというメソッドを呼び出しており、このDriverクラスが以前のQ#プロジェクトで書いていたC#クラス内の処理を行っているように見えます。また、SummaryやDefaultSimulatorみたいな項目もありますが、現状@EntryPointにパラメーターを渡せないで、この辺はまだ変更できなさそうです。もしかすると今後のバージョンアップで機能追加されるかもしれません。