diff --git a/src/Simulation/Core/EntryPointInfo.cs b/src/Simulation/Core/EntryPointInfo.cs new file mode 100644 index 00000000000..dd4373777f0 --- /dev/null +++ b/src/Simulation/Core/EntryPointInfo.cs @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; + +namespace Microsoft.Quantum.Simulation.Core +{ + /// + /// Base class containing information about a Q# entry point. + /// + public class EntryPointInfo + { + public Type Operation { get; } + public Type InType => typeof(I); + public Type OutType => typeof(O); + + public EntryPointInfo(Type operation) => + this.Operation = operation; + } + + /// + /// Base class containing information about an entry point + /// for a Q# executable targeted for a Alfred quantum processor. + /// + public class AlfredEntryPointInfo + : EntryPointInfo + { + public AlfredEntryPointInfo(Type operation) + : base(operation) + { } + } + + /// + /// Base class containing information about an entry point + /// for a Q# executable targeted for a Bruno quantum processor. + /// + public class BrunoEntryPointInfo + : EntryPointInfo + { + public BrunoEntryPointInfo(Type operation) + : base(operation) + { } + } + + /// + /// Base class containing information about an entry point + /// for a Q# executable targeted for a Clementine quantum processor. + /// + public class ClementineEntryPointInfo + : EntryPointInfo + { + public ClementineEntryPointInfo(Type operation) + : base(operation) + { } + } +} diff --git a/src/Simulation/Core/IQuantumMachine.cs b/src/Simulation/Core/IQuantumMachine.cs index 9fc5411bb12..abe2c4538f0 100644 --- a/src/Simulation/Core/IQuantumMachine.cs +++ b/src/Simulation/Core/IQuantumMachine.cs @@ -36,7 +36,7 @@ public interface IQuantumMachine /// Type of input the quantum program receives. /// Type of output the quantum program returns. /// Sampled output of the quantum program - Task> ExecuteAsync(OperationInfo info, TInput input); + Task> ExecuteAsync(EntryPointInfo info, TInput input); /// /// Submits a job to execute a Q# program. @@ -47,6 +47,6 @@ public interface IQuantumMachine /// Type of input the quantum program receives. /// Type of output the quantum program returns. /// A Job instance. Status and results from the execution can be retrieved from this instance. - Task SubmitAsync(OperationInfo info, TInput input); + Task SubmitAsync(EntryPointInfo info, TInput input); } } diff --git a/src/Simulation/Core/OperationInfo.cs b/src/Simulation/Core/OperationInfo.cs deleted file mode 100644 index 1f5bcfd6e74..00000000000 --- a/src/Simulation/Core/OperationInfo.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; - -namespace Microsoft.Quantum.Simulation.Core -{ - /// - /// Contains information about the Q# operation that can be used at runtime. - /// - public class OperationInfo - { - public Type Operation { get; } - public Type InType => typeof(I); - public Type OutType => typeof(O); - public OperationInfo(Type operation) - { - this.Operation = operation; - } - } -} diff --git a/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs b/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs index 628c9b3a884..e5a56b51425 100644 --- a/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs +++ b/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs @@ -19,8 +19,10 @@ open Microsoft.Quantum.QsCompiler.CompilationBuilder open Microsoft.Quantum.QsCompiler.CsharpGeneration open Microsoft.Quantum.QsCompiler.CsharpGeneration.SimulationCode open Microsoft.Quantum.QsCompiler.DataTypes +open Microsoft.Quantum.QsCompiler.ReservedKeywords open Microsoft.Quantum.QsCompiler.SyntaxTree + module SimulationCode = open Microsoft.Quantum.QsCompiler @@ -220,8 +222,7 @@ namespace N1 let tree = parse [(Path.Combine("Circuits","Intrinsic.qs")); fileName] let actual = CodegenContext.Create (tree, ImmutableDictionary.Empty) - |> buildSyntaxTree (Path.GetFullPath fileName |> NonNullable.New) - |> formatSyntaxTree + |> generate (Path.GetFullPath fileName |> NonNullable.New) Assert.Equal(expected |> clearFormatting, actual |> clearFormatting) let testOneBody (builder:SyntaxBuilder) (expected: string list) = @@ -986,17 +987,17 @@ namespace N1 [] let ``buildOperationInfoProperty test`` () = let testOne (_, op) expectedCodeString = - let context = createTestContext op + let context = {createTestContext op with entryPoints = ImmutableArray.Create op.FullName} let (_, operationName) = findClassName context op let inType = op.Signature.ArgumentType |> roslynTypeName context let outType = op.Signature.ReturnType |> roslynTypeName context let codeString = - buildOperationInfoProperty inType outType operationName + buildOperationInfoProperty context inType outType operationName |> formatSyntaxTree Assert.Equal(expectedCodeString |> clearFormatting, codeString |> clearFormatting) let template inType outType operationName = - sprintf @"public static OperationInfo<%s, %s> Info => new OperationInfo<%s, %s>(typeof(%s));" inType outType inType outType operationName + sprintf @"public static EntryPointInfo<%s, %s> Info => new EntryPointInfo<%s, %s>(typeof(%s));" inType outType inType outType operationName template "QVoid" "QVoid" "emptyOperation" |> testOne emptyOperation @@ -2304,9 +2305,14 @@ namespace N1 false |> testOne differentArgsOperation false |> testOne randomOperation - let testOneClass (_,op : QsCallable) (expected : string) = + let testOneClass (_,op : QsCallable) executionTarget (expected : string) = let expected = expected.Replace("%%%", op.SourceFile.Value) - let context = CodegenContext.Create syntaxTree + let assemblyConstants = + new System.Collections.Generic.KeyValuePair<_,_> (AssemblyConstants.ExecutionTarget, executionTarget) + |> Seq.singleton + |> ImmutableDictionary.CreateRange + let compilation = {Namespaces = syntaxTree; EntryPoints = ImmutableArray.Create op.FullName} + let context = CodegenContext.Create (compilation, assemblyConstants) let actual = (buildOperationClass context op).ToFullString() Assert.Equal(expected |> clearFormatting, actual |> clearFormatting) @@ -2322,7 +2328,7 @@ namespace N1 String ICallable.Name => "emptyOperation"; String ICallable.FullName => "Microsoft.Quantum.Testing.emptyOperation"; - public static OperationInfo Info => new OperationInfo(typeof(emptyOperation)); + public static AlfredEntryPointInfo Info => new AlfredEntryPointInfo(typeof(emptyOperation)); public override void Init() { } @@ -2334,7 +2340,7 @@ namespace N1 } } """ - |> testOneClass emptyOperation + |> testOneClass emptyOperation AssemblyConstants.AlfredProcessor """ public abstract partial class randomAbstractOperation : Unitary<(Qubit,Basis,(Pauli,IQArray>,Boolean),Int64)>, ICallable @@ -2357,10 +2363,11 @@ namespace N1 } } } + String ICallable.Name => "randomAbstractOperation"; String ICallable.FullName => "Microsoft.Quantum.Testing.randomAbstractOperation"; - public static OperationInfo<(Qubit, Basis, (Pauli, IQArray>, Boolean), Int64), QVoid> Info => new OperationInfo<(Qubit, Basis, (Pauli, IQArray>, Boolean), Int64), QVoid>(typeof(randomAbstractOperation)); + public static BrunoEntryPointInfo<(Qubit, Basis, (Pauli, IQArray>, Boolean), Int64), QVoid> Info => new BrunoEntryPointInfo<(Qubit, Basis, (Pauli, IQArray>, Boolean), Int64), QVoid>(typeof(randomAbstractOperation)); public override void Init() { } @@ -2372,7 +2379,7 @@ namespace N1 } } """ - |> testOneClass randomAbstractOperation + |> testOneClass randomAbstractOperation AssemblyConstants.BrunoProcessor """ [SourceLocation("%%%", OperationFunctor.Body, 108, 113)] @@ -2388,7 +2395,7 @@ namespace N1 String ICallable.Name => "oneQubitOperation"; String ICallable.FullName => "Microsoft.Quantum.Testing.oneQubitOperation"; - public static OperationInfo Info => new OperationInfo(typeof(oneQubitOperation)); + public static ClementineEntryPointInfo Info => new ClementineEntryPointInfo(typeof(oneQubitOperation)); protected IUnitary X { get; set; } @@ -2442,7 +2449,7 @@ namespace N1 } } """ - |> testOneClass oneQubitOperation + |> testOneClass oneQubitOperation AssemblyConstants.ClementineProcessor [] let ``buildOperationClass - generics`` () = @@ -2474,7 +2481,7 @@ namespace N1 String ICallable.Name => "genCtrl3"; String ICallable.FullName => "Microsoft.Quantum.Compiler.Generics.genCtrl3"; - public static OperationInfo<(__X__, (Int64, (__Y__, __Z__), Result)), QVoid> Info => new OperationInfo<(__X__, (Int64, (__Y__, __Z__), Result)), QVoid>(typeof(genCtrl3<__X__,__Y__,__Z__>)); + public static AlfredEntryPointInfo<(__X__, (Int64, (__Y__, __Z__), Result)), QVoid> Info => new AlfredEntryPointInfo<(__X__, (Int64, (__Y__, __Z__), Result)), QVoid>(typeof(genCtrl3<__X__,__Y__,__Z__>)); public override void Init() { } @@ -2486,7 +2493,7 @@ namespace N1 } } """ - |> testOneClass genCtrl3 + |> testOneClass genCtrl3 AssemblyConstants.AlfredProcessor """ [SourceLocation("%%%", OperationFunctor.Body, 1266, 1272)] @@ -2515,7 +2522,7 @@ namespace N1 String ICallable.Name => "composeImpl"; String ICallable.FullName => "Microsoft.Quantum.Compiler.Generics.composeImpl"; - public static OperationInfo<(ICallable, ICallable, __B__), QVoid> Info => new OperationInfo<(ICallable, ICallable, __B__), QVoid>(typeof(composeImpl<__A__,__B__>)); + public static BrunoEntryPointInfo<(ICallable, ICallable, __B__), QVoid> Info => new BrunoEntryPointInfo<(ICallable, ICallable, __B__), QVoid>(typeof(composeImpl<__A__,__B__>)); public override Func<(ICallable,ICallable,__B__), QVoid> Body => (__in__) => { @@ -2535,7 +2542,7 @@ namespace N1 } } """ - |> testOneClass composeImpl + |> testOneClass composeImpl AssemblyConstants.BrunoProcessor [] let ``buildOperationClass - abstract function`` () = @@ -2549,7 +2556,7 @@ namespace N1 String ICallable.Name => "genF1"; String ICallable.FullName => "Microsoft.Quantum.Compiler.Generics.genF1"; - public static OperationInfo<__A__, QVoid> Info => new OperationInfo<__A__, QVoid>(typeof(genF1<__A__>)); + public static ClementineEntryPointInfo<__A__, QVoid> Info => new ClementineEntryPointInfo<__A__, QVoid>(typeof(genF1<__A__>)); public override void Init() { } @@ -2561,7 +2568,7 @@ namespace N1 } } """ - |> testOneClass genF1 + |> testOneClass genF1 AssemblyConstants.ClementineProcessor [] let ``buildOperationClass - access modifiers`` () = @@ -2573,25 +2580,23 @@ internal partial class EmptyInternalFunction : Function, ICallable { } - String ICallable.Name => "EmptyInternalFunction"; + String ICallable.Name => "EmptyInternalFunction"; + String ICallable.FullName => "Microsoft.Quantum.Compiler.Generics.EmptyInternalFunction"; + public static EntryPointInfo Info => new EntryPointInfo(typeof(EmptyInternalFunction)); - String ICallable.FullName => "Microsoft.Quantum.Compiler.Generics.EmptyInternalFunction"; - - public static OperationInfo Info => new OperationInfo(typeof(EmptyInternalFunction)); - - public override Func Body => (__in__) => - { + public override Func Body => (__in__) => + { #line hidden - return QVoid.Instance; - }; + return QVoid.Instance; + }; - public override void Init() - { - } + public override void Init() + { + } - public override IApplyData __dataIn(QVoid data) => data; + public override IApplyData __dataIn(QVoid data) => data; - public override IApplyData __dataOut(QVoid data) => data; + public override IApplyData __dataOut(QVoid data) => data; public static System.Threading.Tasks.Task Run(IOperationFactory __m__) { @@ -2599,7 +2604,7 @@ internal partial class EmptyInternalFunction : Function, ICallable } } """ - |> testOneClass emptyInternalFunction + |> testOneClass emptyInternalFunction null """ [SourceLocation("%%%", OperationFunctor.Body, 1314, 1316)] @@ -2609,25 +2614,23 @@ internal partial class EmptyInternalOperation : Operation, ICallab { } - String ICallable.Name => "EmptyInternalOperation"; - - String ICallable.FullName => "Microsoft.Quantum.Compiler.Generics.EmptyInternalOperation"; - - public static OperationInfo Info => new OperationInfo(typeof(EmptyInternalOperation)); + String ICallable.Name => "EmptyInternalOperation"; + String ICallable.FullName => "Microsoft.Quantum.Compiler.Generics.EmptyInternalOperation"; + public static EntryPointInfo Info => new EntryPointInfo(typeof(EmptyInternalOperation)); - public override Func Body => (__in__) => - { -#line hidden - return QVoid.Instance; - }; + public override Func Body => (__in__) => + { + #line hidden + return QVoid.Instance; + }; - public override void Init() - { - } + public override void Init() + { + } - public override IApplyData __dataIn(QVoid data) => data; + public override IApplyData __dataIn(QVoid data) => data; - public override IApplyData __dataOut(QVoid data) => data; + public override IApplyData __dataOut(QVoid data) => data; public static System.Threading.Tasks.Task Run(IOperationFactory __m__) { @@ -2635,7 +2638,7 @@ internal partial class EmptyInternalOperation : Operation, ICallab } } """ - |> testOneClass emptyInternalOperation + |> testOneClass emptyInternalOperation null [] @@ -2730,9 +2733,8 @@ internal partial class EmptyInternalOperation : Operation, ICallab String ICallable.Name => "UpdateUdtItems"; String ICallable.FullName => "Microsoft.Quantum.Compiler.Generics.UpdateUdtItems"; - - public static OperationInfo Info => new OperationInfo(typeof(UpdateUdtItems)); - + public static EntryPointInfo Info => new EntryPointInfo(typeof(UpdateUdtItems)); + public override Func Body => (__in__) => { var udt = __in__; @@ -2750,7 +2752,7 @@ internal partial class EmptyInternalOperation : Operation, ICallab } } """ - |> testOneClass UpdateUdtItems + |> testOneClass UpdateUdtItems null """ @@ -2762,8 +2764,7 @@ internal partial class EmptyInternalOperation : Operation, ICallab String ICallable.Name => "emptyFunction"; String ICallable.FullName => "Microsoft.Quantum.Overrides.emptyFunction"; - - public static OperationInfo Info => new OperationInfo(typeof(emptyFunction)); + public static EntryPointInfo Info => new EntryPointInfo(typeof(emptyFunction)); public override void Init() { } @@ -2775,7 +2776,7 @@ internal partial class EmptyInternalOperation : Operation, ICallab } } """ - |> testOneClass emptyFunction + |> testOneClass emptyFunction null """ [SourceLocation("%%%", OperationFunctor.Body, 33, 40)] @@ -2787,8 +2788,7 @@ internal partial class EmptyInternalOperation : Operation, ICallab String ICallable.Name => "intFunction"; String ICallable.FullName => "Microsoft.Quantum.Testing.intFunction"; - - public static OperationInfo Info => new OperationInfo(typeof(intFunction)); + public static EntryPointInfo Info => new EntryPointInfo(typeof(intFunction)); public override Func Body => (__in__) => { @@ -2805,7 +2805,7 @@ internal partial class EmptyInternalOperation : Operation, ICallab } } """ - |> testOneClass intFunction + |> testOneClass intFunction null """ [SourceLocation("%%%", OperationFunctor.Body, 45, 51)] @@ -2826,8 +2826,7 @@ internal partial class EmptyInternalOperation : Operation, ICallab String ICallable.Name => "powFunction"; String ICallable.FullName => "Microsoft.Quantum.Testing.powFunction"; - - public static OperationInfo<(Int64, Int64), Int64> Info => new OperationInfo<(Int64, Int64), Int64>(typeof(powFunction)); + public static EntryPointInfo<(Int64, Int64), Int64> Info => new EntryPointInfo<(Int64, Int64), Int64>(typeof(powFunction)); public override Func<(Int64,Int64), Int64> Body => (__in__) => { @@ -2845,7 +2844,7 @@ internal partial class EmptyInternalOperation : Operation, ICallab } } """ - |> testOneClass powFunction + |> testOneClass powFunction null """ [SourceLocation("%%%", OperationFunctor.Body, 51, 57)] @@ -2866,8 +2865,7 @@ internal partial class EmptyInternalOperation : Operation, ICallab String ICallable.Name => "bigPowFunction"; String ICallable.FullName => "Microsoft.Quantum.Testing.bigPowFunction"; - - public static OperationInfo<(System.Numerics.BigInteger, Int64), System.Numerics.BigInteger> Info => newOperationInfo<(System.Numerics.BigInteger, Int64), System.Numerics.BigInteger>(typeof(bigPowFunction)); + public static EntryPointInfo<(System.Numerics.BigInteger, Int64), System.Numerics.BigInteger> Info => new EntryPointInfo<(System.Numerics.BigInteger, Int64), System.Numerics.BigInteger>(typeof(bigPowFunction)); public override Func<(System.Numerics.BigInteger,Int64), System.Numerics.BigInteger> Body => (__in__) => { @@ -2885,7 +2883,7 @@ internal partial class EmptyInternalOperation : Operation, ICallab } } """ - |> testOneClass bigPowFunction + |> testOneClass bigPowFunction null let private testOneUdt (_,udt) expected = @@ -3223,7 +3221,6 @@ namespace Microsoft.Quantum String ICallable.Name => "emptyFunction"; String ICallable.FullName => "Microsoft.Quantum.emptyFunction"; - public static OperationInfo Info => new OperationInfo(typeof(emptyFunction)); public override void Init() { } public override IApplyData __dataIn(Pair data) => data; public override IApplyData __dataOut(QVoid data) => data; @@ -3241,7 +3238,6 @@ namespace Microsoft.Quantum String ICallable.Name => "emptyOperation"; String ICallable.FullName => "Microsoft.Quantum.emptyOperation"; - public static OperationInfo Info => new OperationInfo(typeof(emptyOperation)); public override void Init() { } public override IApplyData __dataIn(QVoid data) => data; public override IApplyData __dataOut(QVoid data) => data; @@ -3336,7 +3332,7 @@ namespace Microsoft.Quantum let ``find local elements `` () = let oneName = function | QsCustomType udt -> udt.FullName.Name.Value | QsCallable op -> op.FullName.Name.Value let expected = [ "H"; "M"; "Qubits"; "Qubits"; "R"; "S"; "X"; "Z"; ] // Qubits is two times: one for UDT and one for constructor. - let local = syntaxTree |> findLocalElements (Path.GetFullPath (Path.Combine("Circuits","Intrinsic.qs")) |> NonNullable.New) + let local = syntaxTree |> findLocalElements Some (Path.GetFullPath (Path.Combine("Circuits","Intrinsic.qs")) |> NonNullable.New) Assert.Equal(1, local.Length) Assert.Equal("Microsoft.Quantum.Intrinsic", (fst local.[0]).Value) let actual = (snd local.[0]) |> List.map oneName |> List.sort @@ -3376,7 +3372,6 @@ namespace Microsoft.Quantum.Tests.Inline String ICallable.Name => "HelloWorld"; String ICallable.FullName => "Microsoft.Quantum.Tests.Inline.HelloWorld"; - public static OperationInfo Info => new OperationInfo(typeof(HelloWorld)); public override Func Body => (__in__) => { var n = __in__; @@ -3432,7 +3427,6 @@ namespace Microsoft.Quantum.Tests.LineNumbers String ICallable.Name => "TestLineInBlocks"; String ICallable.FullName => "Microsoft.Quantum.Tests.LineNumbers.TestLineInBlocks"; - public static OperationInfo Info => new OperationInfo(typeof(TestLineInBlocks)); protected Allocate Allocate { get; @@ -3670,8 +3664,6 @@ namespace Microsoft.Quantum.Tests.UnitTests String ICallable.Name => "UnitTest1"; String ICallable.FullName => "Microsoft.Quantum.Tests.UnitTests.UnitTest1"; - public static OperationInfo Info => new OperationInfo(typeof(UnitTest1)); - public override Func Body => (__in__) => { #line hidden @@ -3733,8 +3725,6 @@ namespace Microsoft.Quantum.Tests.UnitTests String ICallable.Name => "UnitTest2"; String ICallable.FullName => "Microsoft.Quantum.Tests.UnitTests.UnitTest2"; - public static OperationInfo Info => new OperationInfo(typeof(UnitTest2)); - public override Func Body => (__in__) => { #line hidden diff --git a/src/Simulation/CsharpGeneration/Context.fs b/src/Simulation/CsharpGeneration/Context.fs index b9f93661907..19db9b36520 100644 --- a/src/Simulation/CsharpGeneration/Context.fs +++ b/src/Simulation/CsharpGeneration/Context.fs @@ -65,9 +65,10 @@ type CodegenContext = { current : QsQualifiedName option signature : ResolvedSignature option fileName : string option + entryPoints : IEnumerable } with - static member public Create (syntaxTree, assemblyConstants) = + static member public Create (syntaxTree, assemblyConstants) = let udts = GlobalTypeResolutions syntaxTree let callables = GlobalCallableResolutions syntaxTree let positionInfos = DeclarationLocations.Accumulate syntaxTree @@ -90,12 +91,24 @@ type CodegenContext = { declarationPositions = positionInfos.ToImmutableDictionary((fun g -> g.Key), (fun g -> g.ToImmutableSortedSet())) current = None; fileName = None; - signature = None + signature = None; + entryPoints = ImmutableArray.Empty } - static member public Create syntaxTree = + static member public Create (compilation : QsCompilation, assemblyConstants) = + {CodegenContext.Create(compilation.Namespaces, assemblyConstants) with entryPoints = compilation.EntryPoints} + + static member public Create (compilation : QsCompilation) = + CodegenContext.Create(compilation, ImmutableDictionary.Empty) + + static member public Create (syntaxTree : ImmutableArray) = CodegenContext.Create(syntaxTree, ImmutableDictionary.Empty) + member public this.ExecutionTarget = + match this.assemblyConstants.TryGetValue AssemblyConstants.ExecutionTarget with + | true, name -> name + | false, _ -> null + member public this.AssemblyName = match this.assemblyConstants.TryGetValue AssemblyConstants.AssemblyName with | true, name -> name diff --git a/src/Simulation/CsharpGeneration/Microsoft.Quantum.CsharpGeneration.fsproj b/src/Simulation/CsharpGeneration/Microsoft.Quantum.CsharpGeneration.fsproj index 316ad43e8cc..429f6cce38d 100644 --- a/src/Simulation/CsharpGeneration/Microsoft.Quantum.CsharpGeneration.fsproj +++ b/src/Simulation/CsharpGeneration/Microsoft.Quantum.CsharpGeneration.fsproj @@ -21,7 +21,7 @@ - + diff --git a/src/Simulation/CsharpGeneration/RewriteStep.fs b/src/Simulation/CsharpGeneration/RewriteStep.fs index e8485c64efc..429da44357d 100644 --- a/src/Simulation/CsharpGeneration/RewriteStep.fs +++ b/src/Simulation/CsharpGeneration/RewriteStep.fs @@ -8,6 +8,7 @@ open System.Collections.Generic open System.IO open Microsoft.Quantum.QsCompiler open Microsoft.Quantum.QsCompiler.CsharpGeneration +open Microsoft.Quantum.QsCompiler.DataTypes open Microsoft.Quantum.QsCompiler.ReservedKeywords open Microsoft.Quantum.QsCompiler.SyntaxTree open Microsoft.Quantum.QsCompiler.Transformations.BasicTransformations @@ -36,14 +37,25 @@ type Emitter() = let dir = step.AssemblyConstants.TryGetValue AssemblyConstants.OutputPath |> function | true, outputFolder when outputFolder <> null -> Path.Combine(outputFolder, "src") | _ -> step.Name - let context = CodegenContext.Create (compilation.Namespaces, step.AssemblyConstants) - let allSources = - GetSourceFiles.Apply compilation.Namespaces - |> Seq.filter (fun fileName -> not ((fileName.Value |> Path.GetFileName).EndsWith ".dll")) - for source in allSources do + let context = CodegenContext.Create (compilation, step.AssemblyConstants) + let containsEntryPoint = compilation.EntryPoints.Length <> 0 + let targetsQuantumProcessor = + match step.AssemblyConstants.TryGetValue "ResolvedExecutionTarget" with + | true, target -> target = AssemblyConstants.AlfredProcessor || target = AssemblyConstants.BrunoProcessor || target = AssemblyConstants.ClementineProcessor + | _ -> false + let includeReferences = containsEntryPoint && targetsQuantumProcessor + + let allSources = GetSourceFiles.Apply compilation.Namespaces + let generateCode (fileName : NonNullable) = includeReferences || not ((fileName.Value |> Path.GetFileName).EndsWith ".dll") + + for source in allSources |> Seq.filter generateCode do let content = SimulationCode.generate source context CompilationLoader.GeneratedFile(source, dir, ".g.cs", content) |> ignore + for source in allSources |> Seq.filter (not << generateCode) do + let content = SimulationCode.loadedViaTestNames source context + CompilationLoader.GeneratedFile(source, dir, ".dll.g.cs", content) |> ignore + transformed <- compilation true diff --git a/src/Simulation/CsharpGeneration/SimulationCode.fs b/src/Simulation/CsharpGeneration/SimulationCode.fs index 1c9fcbca2f3..e05cd13c747 100644 --- a/src/Simulation/CsharpGeneration/SimulationCode.fs +++ b/src/Simulation/CsharpGeneration/SimulationCode.fs @@ -929,8 +929,13 @@ module SimulationCode = |> List.map buildOne /// Returns a static property of type OperationInfo using the operation's input and output types. - let buildOperationInfoProperty operationInput operationOutput operationName = - let propertyType = sprintf @"OperationInfo<%s, %s>" operationInput operationOutput + let buildOperationInfoProperty (globalContext:CodegenContext) operationInput operationOutput operationName = + let propertyType = + match globalContext.ExecutionTarget with + | target when target = AssemblyConstants.AlfredProcessor -> sprintf "AlfredEntryPointInfo<%s, %s>" operationInput operationOutput + | target when target = AssemblyConstants.BrunoProcessor -> sprintf "BrunoEntryPointInfo<%s, %s>" operationInput operationOutput + | target when target = AssemblyConstants.ClementineProcessor -> sprintf "ClementineEntryPointInfo<%s, %s>" operationInput operationOutput + | _ -> sprintf "EntryPointInfo<%s, %s>" operationInput operationOutput let operationType = simpleBase operationName let newInstanceArgs = [``invoke`` (``ident`` "typeof") ``(`` [operationType.Type] ``)``] let newInstance = ``new`` (``type`` [propertyType]) ``(`` newInstanceArgs ``)`` @@ -1350,7 +1355,14 @@ module SimulationCode = let outType = op.Signature.ReturnType |> roslynTypeName context let constructors = [ (buildConstructor context name) ] - let properties = buildName name :: buildFullName context.current.Value :: buildOperationInfoProperty inType outType nonGenericName :: buildOpsProperties context opNames + let properties = + let opProperties = buildOpsProperties context opNames + buildName name :: + buildFullName context.current.Value :: + if globalContext.entryPoints |> Seq.contains op.FullName then + buildOperationInfoProperty globalContext inType outType nonGenericName :: + opProperties + else opProperties let baseOp = if isFunction op then @@ -1553,22 +1565,20 @@ module SimulationCode = generator.Apply elements // Returns only those namespaces and their elements that are defined for the given file. - let findLocalElements fileName syntaxTree = + let findLocalElements selector fileName syntaxTree = let path = match CompilationBuilder.CompilationUnitManager.TryGetUri fileName with | true, uri -> uri.AbsolutePath |> NonNullable.New | false, _ -> NonNullable.New "" syntaxTree - |> Seq.map (fun ns -> (ns.Name, (FilterBySourceFile.Apply (ns, path)).Elements |> Seq.toList)) + |> Seq.map (fun ns -> (ns.Name, (FilterBySourceFile.Apply (ns, path)).Elements |> Seq.choose selector |> Seq.toList)) |> Seq.sortBy fst |> Seq.filter (fun (_,elements) -> not elements.IsEmpty) |> Seq.toList // Builds the C# syntaxTree for the Q# elements defined in the given file. - let buildSyntaxTree (fileName : NonNullable) (globalContext : CodegenContext) = - let context = {globalContext with fileName = Some fileName.Value} + let buildSyntaxTree localElements (context : CodegenContext) = let usings = autoNamespaces |> List.map (fun ns -> ``using`` ns) - let localElements = findLocalElements fileName context.allQsElements let attributes = localElements |> List.map (snd >> buildDeclarationAttributes) |> List.concat let namespaces = localElements |> List.map (buildNamespace context) @@ -1603,11 +1613,28 @@ module SimulationCode = let msg = l.LoaderExceptions |> Array.fold (fun msg e -> msg + ";" + e.Message) "" failwith msg + // Builds the SyntaxTree for callables and types loaded via test names, + // formats it and returns it as a string + let loadedViaTestNames (dllName : NonNullable) globalContext = + let isLoadedViaTestName nsElement = + let asOption = function | Value _ -> Some nsElement | _ -> None + match nsElement with + | QsCallable c as e -> SymbolResolution.TryGetTestName c.Attributes + | QsCustomType t as e -> SymbolResolution.TryGetTestName t.Attributes + |> asOption + let context = {globalContext with fileName = Some dllName.Value} + let localElements = findLocalElements isLoadedViaTestName dllName context.allQsElements + buildSyntaxTree localElements context + |> formatSyntaxTree + // Main entry method for a CodeGenerator. // Builds the SyntaxTree for the given Q# syntax tree, formats it and returns it as a string - let generate fileName globalContext = - buildSyntaxTree fileName globalContext + let generate (fileName : NonNullable) globalContext = + let context = {globalContext with fileName = Some fileName.Value} + let localElements = findLocalElements Some fileName context.allQsElements + buildSyntaxTree localElements context |> formatSyntaxTree + \ No newline at end of file diff --git a/src/Simulation/QCTraceSimulator.Tests/Tests.Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.csproj b/src/Simulation/QCTraceSimulator.Tests/Tests.Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.csproj index 84a70ac3e32..81e1b1776cd 100644 --- a/src/Simulation/QCTraceSimulator.Tests/Tests.Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.csproj +++ b/src/Simulation/QCTraceSimulator.Tests/Tests.Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.csproj @@ -1,4 +1,4 @@ - + diff --git a/src/Simulation/QsharpCore/Diagnostics/UnitTests.qs b/src/Simulation/QsharpCore/Diagnostics/UnitTests.qs index 7134d071b67..6b1ac06273c 100644 --- a/src/Simulation/QsharpCore/Diagnostics/UnitTests.qs +++ b/src/Simulation/QsharpCore/Diagnostics/UnitTests.qs @@ -14,6 +14,16 @@ namespace Microsoft.Quantum.Diagnostics { /// @Attribute() newtype Test = (ExecutionTarget : String); + + /// # Summary + /// Compiler recognized attribute via which an alternative name can be defined + /// that may be used when loading a type or callable for testing purposes. + /// + /// # Input + /// Defined name for testing purposes. + /// The String is expected to contain a fully qualified name. + @Attribute() + newtype EnableTestingViaName = String; } diff --git a/src/Simulation/QsharpCore/Microsoft.Quantum.QSharp.Core.csproj b/src/Simulation/QsharpCore/Microsoft.Quantum.QSharp.Core.csproj index 23d49f6ad19..23760447b52 100644 --- a/src/Simulation/QsharpCore/Microsoft.Quantum.QSharp.Core.csproj +++ b/src/Simulation/QsharpCore/Microsoft.Quantum.QSharp.Core.csproj @@ -1,4 +1,4 @@ - + diff --git a/src/Simulation/Simulators.Tests/Tests.Microsoft.Quantum.Simulation.Simulators.csproj b/src/Simulation/Simulators.Tests/Tests.Microsoft.Quantum.Simulation.Simulators.csproj index c75f9a56eea..5235cdd9332 100644 --- a/src/Simulation/Simulators.Tests/Tests.Microsoft.Quantum.Simulation.Simulators.csproj +++ b/src/Simulation/Simulators.Tests/Tests.Microsoft.Quantum.Simulation.Simulators.csproj @@ -1,4 +1,4 @@ - + diff --git a/src/Simulation/Simulators/Microsoft.Quantum.Simulation.Simulators.csproj b/src/Simulation/Simulators/Microsoft.Quantum.Simulation.Simulators.csproj index 6119a2f5bad..1cc02f62456 100644 --- a/src/Simulation/Simulators/Microsoft.Quantum.Simulation.Simulators.csproj +++ b/src/Simulation/Simulators/Microsoft.Quantum.Simulation.Simulators.csproj @@ -1,4 +1,4 @@ - +