diff --git a/Simulation.sln b/Simulation.sln index f3e268e45ec..8b4957e793d 100644 --- a/Simulation.sln +++ b/Simulation.sln @@ -9,7 +9,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Quantum.Simulatio EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Quantum.Simulation.Common", "src\Simulation\Common\Microsoft.Quantum.Simulation.Common.csproj", "{8EC46ADB-7FAA-49EA-BA63-E7B32C4F4445}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Quantum.Simulators", "src\Simulation\Simulators\Microsoft.Quantum.Simulators.csproj", "{72B7E75C-D305-45BD-929E-C86298AAA8DE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Quantum.Simulators", "src\Simulation\Simulators.Core\Microsoft.Quantum.Simulators.csproj", "{72B7E75C-D305-45BD-929E-C86298AAA8DE}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests.Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime", "src\Simulation\QCTraceSimulator.Tests\Tests.Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.csproj", "{DD50D2D9-2765-449B-8C4B-835A428E160D}" EndProject @@ -71,6 +71,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Simulation", "Simulation", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Quantum.QSharp.Foundation", "src\Simulation\QsharpFoundation\Microsoft.Quantum.QSharp.Foundation.csproj", "{DB45AD73-4D91-43F3-85CC-C63614A96FB0}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Quantum.Type2.Core", "src\Simulation\Type2Core\Microsoft.Quantum.Type2.Core.csproj", "{AF6CD304-8E03-433D-AAA2-6E0094B53071}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Quantum.Simulators.Type2", "src\Simulation\Simulators.Type2\Microsoft.Quantum.Simulators.Type2.csproj", "{E7163371-74D5-4DAD-AB04-8DA3FA1AD46F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Microsoft.Quantum.Simulators.Type2", "src\Simulation\Simulators.Type2.Tests\Tests.Microsoft.Quantum.Simulators.Type2.csproj", "{ED3D7040-4B3F-4217-A75E-9DF63DD84707}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Simulators.Tests", "Simulators.Tests", "{CF48986A-B487-407F-98A7-97AED29C6A43}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestProjects", "TestProjects", "{F5F80AEA-34F4-4E1D-8145-0634E9DCF2C3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IntrinsicTests", "src\Simulation\Simulators.Tests\TestProjects\IntrinsicTests\IntrinsicTests.csproj", "{4EF958CA-B4A6-4E5F-924A-100B5615BEC3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -499,6 +511,70 @@ Global {DB45AD73-4D91-43F3-85CC-C63614A96FB0}.RelWithDebInfo|Any CPU.Build.0 = Debug|Any CPU {DB45AD73-4D91-43F3-85CC-C63614A96FB0}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU {DB45AD73-4D91-43F3-85CC-C63614A96FB0}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU + {AF6CD304-8E03-433D-AAA2-6E0094B53071}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AF6CD304-8E03-433D-AAA2-6E0094B53071}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AF6CD304-8E03-433D-AAA2-6E0094B53071}.Debug|x64.ActiveCfg = Debug|Any CPU + {AF6CD304-8E03-433D-AAA2-6E0094B53071}.Debug|x64.Build.0 = Debug|Any CPU + {AF6CD304-8E03-433D-AAA2-6E0094B53071}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU + {AF6CD304-8E03-433D-AAA2-6E0094B53071}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU + {AF6CD304-8E03-433D-AAA2-6E0094B53071}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU + {AF6CD304-8E03-433D-AAA2-6E0094B53071}.MinSizeRel|x64.Build.0 = Debug|Any CPU + {AF6CD304-8E03-433D-AAA2-6E0094B53071}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AF6CD304-8E03-433D-AAA2-6E0094B53071}.Release|Any CPU.Build.0 = Release|Any CPU + {AF6CD304-8E03-433D-AAA2-6E0094B53071}.Release|x64.ActiveCfg = Release|Any CPU + {AF6CD304-8E03-433D-AAA2-6E0094B53071}.Release|x64.Build.0 = Release|Any CPU + {AF6CD304-8E03-433D-AAA2-6E0094B53071}.RelWithDebInfo|Any CPU.ActiveCfg = Debug|Any CPU + {AF6CD304-8E03-433D-AAA2-6E0094B53071}.RelWithDebInfo|Any CPU.Build.0 = Debug|Any CPU + {AF6CD304-8E03-433D-AAA2-6E0094B53071}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU + {AF6CD304-8E03-433D-AAA2-6E0094B53071}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU + {E7163371-74D5-4DAD-AB04-8DA3FA1AD46F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E7163371-74D5-4DAD-AB04-8DA3FA1AD46F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E7163371-74D5-4DAD-AB04-8DA3FA1AD46F}.Debug|x64.ActiveCfg = Debug|Any CPU + {E7163371-74D5-4DAD-AB04-8DA3FA1AD46F}.Debug|x64.Build.0 = Debug|Any CPU + {E7163371-74D5-4DAD-AB04-8DA3FA1AD46F}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU + {E7163371-74D5-4DAD-AB04-8DA3FA1AD46F}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU + {E7163371-74D5-4DAD-AB04-8DA3FA1AD46F}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU + {E7163371-74D5-4DAD-AB04-8DA3FA1AD46F}.MinSizeRel|x64.Build.0 = Debug|Any CPU + {E7163371-74D5-4DAD-AB04-8DA3FA1AD46F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E7163371-74D5-4DAD-AB04-8DA3FA1AD46F}.Release|Any CPU.Build.0 = Release|Any CPU + {E7163371-74D5-4DAD-AB04-8DA3FA1AD46F}.Release|x64.ActiveCfg = Release|Any CPU + {E7163371-74D5-4DAD-AB04-8DA3FA1AD46F}.Release|x64.Build.0 = Release|Any CPU + {E7163371-74D5-4DAD-AB04-8DA3FA1AD46F}.RelWithDebInfo|Any CPU.ActiveCfg = Debug|Any CPU + {E7163371-74D5-4DAD-AB04-8DA3FA1AD46F}.RelWithDebInfo|Any CPU.Build.0 = Debug|Any CPU + {E7163371-74D5-4DAD-AB04-8DA3FA1AD46F}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU + {E7163371-74D5-4DAD-AB04-8DA3FA1AD46F}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU + {ED3D7040-4B3F-4217-A75E-9DF63DD84707}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ED3D7040-4B3F-4217-A75E-9DF63DD84707}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ED3D7040-4B3F-4217-A75E-9DF63DD84707}.Debug|x64.ActiveCfg = Debug|Any CPU + {ED3D7040-4B3F-4217-A75E-9DF63DD84707}.Debug|x64.Build.0 = Debug|Any CPU + {ED3D7040-4B3F-4217-A75E-9DF63DD84707}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU + {ED3D7040-4B3F-4217-A75E-9DF63DD84707}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU + {ED3D7040-4B3F-4217-A75E-9DF63DD84707}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU + {ED3D7040-4B3F-4217-A75E-9DF63DD84707}.MinSizeRel|x64.Build.0 = Debug|Any CPU + {ED3D7040-4B3F-4217-A75E-9DF63DD84707}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ED3D7040-4B3F-4217-A75E-9DF63DD84707}.Release|Any CPU.Build.0 = Release|Any CPU + {ED3D7040-4B3F-4217-A75E-9DF63DD84707}.Release|x64.ActiveCfg = Release|Any CPU + {ED3D7040-4B3F-4217-A75E-9DF63DD84707}.Release|x64.Build.0 = Release|Any CPU + {ED3D7040-4B3F-4217-A75E-9DF63DD84707}.RelWithDebInfo|Any CPU.ActiveCfg = Debug|Any CPU + {ED3D7040-4B3F-4217-A75E-9DF63DD84707}.RelWithDebInfo|Any CPU.Build.0 = Debug|Any CPU + {ED3D7040-4B3F-4217-A75E-9DF63DD84707}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU + {ED3D7040-4B3F-4217-A75E-9DF63DD84707}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU + {4EF958CA-B4A6-4E5F-924A-100B5615BEC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4EF958CA-B4A6-4E5F-924A-100B5615BEC3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4EF958CA-B4A6-4E5F-924A-100B5615BEC3}.Debug|x64.ActiveCfg = Debug|Any CPU + {4EF958CA-B4A6-4E5F-924A-100B5615BEC3}.Debug|x64.Build.0 = Debug|Any CPU + {4EF958CA-B4A6-4E5F-924A-100B5615BEC3}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU + {4EF958CA-B4A6-4E5F-924A-100B5615BEC3}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU + {4EF958CA-B4A6-4E5F-924A-100B5615BEC3}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU + {4EF958CA-B4A6-4E5F-924A-100B5615BEC3}.MinSizeRel|x64.Build.0 = Debug|Any CPU + {4EF958CA-B4A6-4E5F-924A-100B5615BEC3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4EF958CA-B4A6-4E5F-924A-100B5615BEC3}.Release|Any CPU.Build.0 = Release|Any CPU + {4EF958CA-B4A6-4E5F-924A-100B5615BEC3}.Release|x64.ActiveCfg = Release|Any CPU + {4EF958CA-B4A6-4E5F-924A-100B5615BEC3}.Release|x64.Build.0 = Release|Any CPU + {4EF958CA-B4A6-4E5F-924A-100B5615BEC3}.RelWithDebInfo|Any CPU.ActiveCfg = Debug|Any CPU + {4EF958CA-B4A6-4E5F-924A-100B5615BEC3}.RelWithDebInfo|Any CPU.Build.0 = Debug|Any CPU + {4EF958CA-B4A6-4E5F-924A-100B5615BEC3}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU + {4EF958CA-B4A6-4E5F-924A-100B5615BEC3}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -532,6 +608,12 @@ Global {D292BF18-3956-4827-820E-254C3F81EF09} = {09C842CB-930C-4C7D-AD5F-E30DE4A55820} {9008B252-2DF7-404B-B626-D4497BB70A05} = {BC562DAE-FE2B-4A8C-880C-C546F83F99E4} {DB45AD73-4D91-43F3-85CC-C63614A96FB0} = {9008B252-2DF7-404B-B626-D4497BB70A05} + {AF6CD304-8E03-433D-AAA2-6E0094B53071} = {9008B252-2DF7-404B-B626-D4497BB70A05} + {E7163371-74D5-4DAD-AB04-8DA3FA1AD46F} = {9008B252-2DF7-404B-B626-D4497BB70A05} + {ED3D7040-4B3F-4217-A75E-9DF63DD84707} = {9008B252-2DF7-404B-B626-D4497BB70A05} + {CF48986A-B487-407F-98A7-97AED29C6A43} = {9008B252-2DF7-404B-B626-D4497BB70A05} + {F5F80AEA-34F4-4E1D-8145-0634E9DCF2C3} = {CF48986A-B487-407F-98A7-97AED29C6A43} + {4EF958CA-B4A6-4E5F-924A-100B5615BEC3} = {F5F80AEA-34F4-4E1D-8145-0634E9DCF2C3} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {929C0464-86D8-4F70-8835-0A5EAF930821} diff --git a/bootstrap.ps1 b/bootstrap.ps1 index 861a83f3f34..251698dff4f 100644 --- a/bootstrap.ps1 +++ b/bootstrap.ps1 @@ -7,7 +7,11 @@ Push-Location (Join-Path $PSScriptRoot "src/Simulation/CsharpGeneration") .\FindNuspecReferences.ps1 Pop-Location -Push-Location (Join-Path $PSScriptRoot "src/Simulation/Simulators") +Push-Location (Join-Path $PSScriptRoot "src/Simulation/Simulators.Core") + .\FindNuspecReferences.ps1 +Pop-Location + +Push-Location (Join-Path $PSScriptRoot "src/Simulation/Simulators.Type2") .\FindNuspecReferences.ps1 Pop-Location diff --git a/build/manifest.ps1 b/build/manifest.ps1 index c45029d5026..fbe7f793736 100644 --- a/build/manifest.ps1 +++ b/build/manifest.ps1 @@ -23,9 +23,10 @@ ".\src\Simulation\EntryPointDriver\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.EntryPointDriver.dll", ".\src\Simulation\QsharpCore\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.QSharp.Core.dll", ".\src\Simulation\QsharpFoundation\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.QSharp.Foundation.dll", - ".\src\Simulation\Simulators\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.Simulation.Common.dll", - ".\src\Simulation\Simulators\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.dll", - ".\src\Simulation\Simulators\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.Simulators.dll", + ".\src\Simulation\Simulators.Core\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.Simulation.Common.dll", + ".\src\Simulation\Simulators.Core\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.dll", + ".\src\Simulation\Simulators.Core\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.Simulators.dll", + ".\src\Simulation\Simulators.Type2\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.Simulators.Type2.dll", ".\src\Xunit\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.Xunit.dll" ) | ForEach-Object { Get-Item (Join-Path $PSScriptRoot (Join-Path ".." $_)) }; } | Write-Output; diff --git a/build/pack.ps1 b/build/pack.ps1 index 8bad978434d..65dc7d01a94 100644 --- a/build/pack.ps1 +++ b/build/pack.ps1 @@ -66,7 +66,9 @@ Pack-Dotnet '../src/Simulation/EntryPointDriver/Microsoft.Quantum.EntryPointDriv Pack-Dotnet '../src/Simulation/Core/Microsoft.Quantum.Runtime.Core.csproj' Pack-Dotnet '../src/Simulation/QSharpFoundation/Microsoft.Quantum.QSharp.Foundation.csproj' Pack-Dotnet '../src/Simulation/QsharpCore/Microsoft.Quantum.QSharp.Core.csproj' -Pack-One '../src/Simulation/Simulators/Microsoft.Quantum.Simulators.nuspec' +Pack-Dotnet '../src/Simulation/Type2Core/Microsoft.Quantum.Type2.Core.csproj' +Pack-One '../src/Simulation/Simulators.Core/Microsoft.Quantum.Simulators.nuspec' +Pack-One '../src/Simulation/Simulators.Type2/Microsoft.Quantum.Simulators.Type2.nuspec' Pack-One '../src/Quantum.Development.Kit/Microsoft.Quantum.Development.Kit.nuspec' Pack-One '../src/Xunit/Microsoft.Quantum.Xunit.csproj' diff --git a/src/Simulation/Common/Microsoft.Quantum.Simulation.Common.csproj b/src/Simulation/Common/Microsoft.Quantum.Simulation.Common.csproj index db67c8130ed..5772508edfb 100644 --- a/src/Simulation/Common/Microsoft.Quantum.Simulation.Common.csproj +++ b/src/Simulation/Common/Microsoft.Quantum.Simulation.Common.csproj @@ -14,7 +14,6 @@ - diff --git a/src/Simulation/Common/QubitManager.cs b/src/Simulation/Common/QubitManager.cs index 9bc54dfce3d..1802583f793 100644 --- a/src/Simulation/Common/QubitManager.cs +++ b/src/Simulation/Common/QubitManager.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using Microsoft.Quantum.Intrinsic; using Microsoft.Quantum.Simulation.Core; using Microsoft.Quantum.Simulation.Simulators.Exceptions; diff --git a/src/Simulation/Common/Simulators.Dev.props b/src/Simulation/Common/Simulators.Dev.props index 7c44b437a38..ee61a11c722 100644 --- a/src/Simulation/Common/Simulators.Dev.props +++ b/src/Simulation/Common/Simulators.Dev.props @@ -23,7 +23,7 @@ - + diff --git a/src/Simulation/Common/Simulators.Type2.Dev.props b/src/Simulation/Common/Simulators.Type2.Dev.props new file mode 100644 index 00000000000..ce27923c3fd --- /dev/null +++ b/src/Simulation/Common/Simulators.Type2.Dev.props @@ -0,0 +1,42 @@ + + + + + bin\$(BuildConfiguration)\$(TargetFramework)\$(AssemblyName).xml + $([MSBuild]::NormalizeDirectory($(MSBuildThisFileDirectory)..\..\..\)) + $([MSBuild]::NormalizePath($(EnlistmentRoot)src/Simulation/Native/build/)) + + + + $([MSBuild]::NormalizePath($(NativeBuildPath)/libMicrosoft.Quantum.Simulator.Runtime.dylib)) + $([MSBuild]::NormalizePath($(NativeBuildPath)/libMicrosoft.Quantum.Simulator.Runtime.so)) + $([MSBuild]::NormalizePath($(NativeBuildPath)/Release/Microsoft.Quantum.Simulator.Runtime.dll)) + $([MSBuild]::NormalizePath($(NativeBuildPath)/Debug/Microsoft.Quantum.Simulator.Runtime.dll)) + $(QsimDllMac) + $(QsimDllLinux) + $(QsimDllWindowsRelease) + $(QsimDllWindowsDebug) + + + + + + + + + + + + Microsoft.Quantum.Simulator.Runtime.dll + PreserveNewest + false + + + + + + + + + + diff --git a/src/Simulation/Core/Properties/AssemblyInfo.cs b/src/Simulation/Core/Properties/AssemblyInfo.cs index c2a5d12dced..4ecfaf27ed6 100644 --- a/src/Simulation/Core/Properties/AssemblyInfo.cs +++ b/src/Simulation/Core/Properties/AssemblyInfo.cs @@ -7,3 +7,4 @@ // Allow the test assembly to use our internal methods [assembly: InternalsVisibleTo("Tests.Microsoft.Quantum.Simulators" + SigningConstants.PUBLIC_KEY)] +[assembly: InternalsVisibleTo("Tests.Microsoft.Quantum.Simulators.Type2" + SigningConstants.PUBLIC_KEY)] diff --git a/src/Simulation/CsharpGeneration.Tests/Tests.CsharpGeneration.fsproj b/src/Simulation/CsharpGeneration.Tests/Tests.CsharpGeneration.fsproj index 906f812078b..4e83f9f6035 100644 --- a/src/Simulation/CsharpGeneration.Tests/Tests.CsharpGeneration.fsproj +++ b/src/Simulation/CsharpGeneration.Tests/Tests.CsharpGeneration.fsproj @@ -51,10 +51,8 @@ - - - + diff --git a/src/Simulation/EntryPointDriver/Microsoft.Quantum.EntryPointDriver.csproj b/src/Simulation/EntryPointDriver/Microsoft.Quantum.EntryPointDriver.csproj index a506e16a6f9..e78cf42f721 100644 --- a/src/Simulation/EntryPointDriver/Microsoft.Quantum.EntryPointDriver.csproj +++ b/src/Simulation/EntryPointDriver/Microsoft.Quantum.EntryPointDriver.csproj @@ -26,8 +26,7 @@ - - + diff --git a/src/Simulation/QsharpCore/Diagnostics/DeprecatedDiagnostics.qs b/src/Simulation/QsharpCore/Diagnostics/DeprecatedDiagnostics.qs deleted file mode 100644 index 05a0a31185d..00000000000 --- a/src/Simulation/QsharpCore/Diagnostics/DeprecatedDiagnostics.qs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -namespace Microsoft.Quantum.Extensions.Diagnostics { - - /// # Deprecated - /// Please use @"microsoft.quantum.diagnostics.dumpmachine". - @Deprecated("Microsoft.Quantum.Diagnostics.DumpMachine") - function DumpMachine<'T> (location : 'T) : Unit { - return Microsoft.Quantum.Diagnostics.DumpMachine(location); - } - - /// # Deprecated - /// Please use @"microsoft.quantum.diagnostics.dumpregister". - @Deprecated("Microsoft.Quantum.Diagnostics.DumpRegister") - function DumpRegister<'T> (location : 'T, qubits : Qubit[]) : Unit { - return Microsoft.Quantum.Diagnostics.DumpRegister(location, qubits); - } - -} diff --git a/src/Simulation/QsharpCore/Diagnostics/DeprecatedTesting.qs b/src/Simulation/QsharpCore/Diagnostics/DeprecatedTesting.qs deleted file mode 100644 index 22886674a90..00000000000 --- a/src/Simulation/QsharpCore/Diagnostics/DeprecatedTesting.qs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -namespace Microsoft.Quantum.Extensions.Testing { - open Microsoft.Quantum.Math; - - /// # Deprecated - /// Please use @"microsoft.quantum.diagnostics.assertqubit". - @Deprecated("Microsoft.Quantum.Diagnostics.AssertQubit") - operation AssertQubit(expected : Result, q : Qubit) : Unit { - Microsoft.Quantum.Diagnostics.AssertQubit(expected, q); - } - - /// # Deprecated - /// Please use @"microsoft.quantum.diagnostics.assertqubitwithintolerance". - @Deprecated("Microsoft.Quantum.Diagnostics.AssertQubitWithinTolerance") - operation AssertQubitTol(expected : Result, q : Qubit, tolerance : Double) : Unit { - Microsoft.Quantum.Diagnostics.AssertQubitWithinTolerance(expected, q, tolerance); - } - - /// # Deprecated - /// Please use @"microsoft.quantum.diagnostics.assertqubitisinstatewithintolerance". - @Deprecated("Microsoft.Quantum.Diagnostics.AssertQubitIsInStateWithinTolerance") - operation AssertQubitState(expected : (Complex, Complex), register : Qubit, tolerance : Double) : Unit { - Microsoft.Quantum.Diagnostics.AssertQubitIsInStateWithinTolerance(expected, register, tolerance); - } - - /// # Deprecated - /// Please use @"microsoft.quantum.diagnostics.assertoperationsequalreferenced". - /// Note that the order of the arguments to this operation has changed. - @Deprecated("Microsoft.Quantum.Diagnostics.AssertOperationsEqualReferenced") - operation AssertOperationsEqualReferenced(actual : (Qubit[] => Unit), expected : (Qubit[] => Unit is Adj), nQubits : Int) : Unit { - Microsoft.Quantum.Diagnostics.AssertOperationsEqualReferenced(nQubits, actual, expected); - } - - /// # Deprecated - /// Please use @"microsoft.quantum.diagnostics.assertoperationsequalinplace". - /// Note that the order of the arguments to this operation has changed. - @Deprecated("Microsoft.Quantum.Diagnostics.AssertOperationsEqualInPlace") - operation AssertOperationsEqualInPlace(actual : (Qubit[] => Unit), expected : (Qubit[] => Unit is Adj), nQubits : Int) : Unit { - Microsoft.Quantum.Diagnostics.AssertOperationsEqualInPlace(nQubits, actual, expected); - } - - /// # Deprecated - /// Please use @"microsoft.quantum.diagnostics.assertoperationsequalinplaceCompBasis". - /// Note that the order of the arguments to this operation has changed. - @Deprecated("Microsoft.Quantum.Diagnostics.AssertOperationsEqualInPlaceCompBasis") - operation AssertOperationsEqualInPlaceCompBasis(actual : (Qubit[] => Unit), expected : (Qubit[] => Unit is Adj), nQubits : Int) : Unit { - Microsoft.Quantum.Diagnostics.AssertOperationsEqualInPlaceCompBasis(nQubits, actual, expected); - } - - /// # Deprecated - /// Please use @"microsoft.quantum.diagnostics.assertallzero". - @Deprecated("Microsoft.Quantum.Diagnostics.AssertAllZero") - operation AssertAllZero(qubits : Qubit[]) : Unit is Adj + Ctl { - Microsoft.Quantum.Diagnostics.AssertAllZero(qubits); - } - - /// # Deprecated - /// Please use @"microsoft.quantum.diagnostics.assertallzerowithintolerance". - @Deprecated("Microsoft.Quantum.Diagnostics.AssertAllZeroWithinTolerance") - operation AssertAllZeroTol(qubits : Qubit[], tolerance : Double) : Unit is Adj + Ctl { - Microsoft.Quantum.Diagnostics.AssertAllZeroWithinTolerance(qubits, tolerance); - } - -} diff --git a/src/Simulation/QsharpFoundation/Diagnostics/Dump.qs b/src/Simulation/QsharpFoundation/Diagnostics/Dump.qs index 6484a93cc35..316b3305290 100644 --- a/src/Simulation/QsharpFoundation/Diagnostics/Dump.qs +++ b/src/Simulation/QsharpFoundation/Diagnostics/Dump.qs @@ -26,6 +26,7 @@ namespace Microsoft.Quantum.Diagnostics { /// one-dimensional array of complex numbers, in which each element represents /// the amplitudes of the probability of measuring the corresponding state. function DumpMachine<'T> (location : 'T) : Unit { + body intrinsic; } /// # Summary @@ -56,6 +57,7 @@ namespace Microsoft.Quantum.Diagnostics { /// If the given qubits are entangled with some other qubit and their /// state can't be separated, it just reports that the qubits are entangled. function DumpRegister<'T> (location : 'T, qubits : Qubit[]) : Unit { + body intrinsic; } } diff --git a/src/Simulation/QsharpCore/Diagnostics/Facts.qs b/src/Simulation/QsharpFoundation/Diagnostics/Facts.qs similarity index 100% rename from src/Simulation/QsharpCore/Diagnostics/Facts.qs rename to src/Simulation/QsharpFoundation/Diagnostics/Facts.qs diff --git a/src/Simulation/QsharpCore/Diagnostics/Properties/NamespaceInfo.qs b/src/Simulation/QsharpFoundation/Diagnostics/Properties/NamespaceInfo.qs similarity index 100% rename from src/Simulation/QsharpCore/Diagnostics/Properties/NamespaceInfo.qs rename to src/Simulation/QsharpFoundation/Diagnostics/Properties/NamespaceInfo.qs diff --git a/src/Simulation/QsharpFoundation/Environment.qs b/src/Simulation/QsharpFoundation/Environment.qs index 7cc91153d50..30407778e14 100644 --- a/src/Simulation/QsharpFoundation/Environment.qs +++ b/src/Simulation/QsharpFoundation/Environment.qs @@ -15,7 +15,7 @@ namespace Microsoft.Quantum.Environment { /// # See Also /// - GetQubitsAvailableToBorrow operation GetQubitsAvailableToUse () : Int { - return -1; + body intrinsic; } /// # Summary @@ -31,7 +31,7 @@ namespace Microsoft.Quantum.Environment { /// # See Also /// - GetQubitsAvailableToUse operation GetQubitsAvailableToBorrow () : Int { - return -1; + body intrinsic; } } diff --git a/src/Simulation/QsharpFoundation/Microsoft.Quantum.QSharp.Foundation.csproj b/src/Simulation/QsharpFoundation/Microsoft.Quantum.QSharp.Foundation.csproj index f1400e76f30..48a339e16d8 100644 --- a/src/Simulation/QsharpFoundation/Microsoft.Quantum.QSharp.Foundation.csproj +++ b/src/Simulation/QsharpFoundation/Microsoft.Quantum.QSharp.Foundation.csproj @@ -1,4 +1,4 @@ - + diff --git a/src/Simulation/QsharpCore/Random/Convienence.qs b/src/Simulation/QsharpFoundation/Random/Convienence.qs similarity index 100% rename from src/Simulation/QsharpCore/Random/Convienence.qs rename to src/Simulation/QsharpFoundation/Random/Convienence.qs diff --git a/src/Simulation/QsharpCore/Random/Internal.qs b/src/Simulation/QsharpFoundation/Random/Internal.qs similarity index 100% rename from src/Simulation/QsharpCore/Random/Internal.qs rename to src/Simulation/QsharpFoundation/Random/Internal.qs diff --git a/src/Simulation/QsharpCore/Random/Intrinsic.qs b/src/Simulation/QsharpFoundation/Random/Intrinsic.qs similarity index 100% rename from src/Simulation/QsharpCore/Random/Intrinsic.qs rename to src/Simulation/QsharpFoundation/Random/Intrinsic.qs diff --git a/src/Simulation/QsharpCore/Random/Normal.qs b/src/Simulation/QsharpFoundation/Random/Normal.qs similarity index 100% rename from src/Simulation/QsharpCore/Random/Normal.qs rename to src/Simulation/QsharpFoundation/Random/Normal.qs diff --git a/src/Simulation/QsharpCore/Random/Types.qs b/src/Simulation/QsharpFoundation/Random/Types.qs similarity index 100% rename from src/Simulation/QsharpCore/Random/Types.qs rename to src/Simulation/QsharpFoundation/Random/Types.qs diff --git a/src/Simulation/QsharpCore/Random/Uniform.qs b/src/Simulation/QsharpFoundation/Random/Uniform.qs similarity index 100% rename from src/Simulation/QsharpCore/Random/Uniform.qs rename to src/Simulation/QsharpFoundation/Random/Uniform.qs diff --git a/src/Simulation/Simulators/.gitignore b/src/Simulation/Simulators.Core/.gitignore similarity index 100% rename from src/Simulation/Simulators/.gitignore rename to src/Simulation/Simulators.Core/.gitignore diff --git a/src/Simulation/Simulators/FindNuspecReferences.ps1 b/src/Simulation/Simulators.Core/FindNuspecReferences.ps1 similarity index 96% rename from src/Simulation/Simulators/FindNuspecReferences.ps1 rename to src/Simulation/Simulators.Core/FindNuspecReferences.ps1 index 993f4b0948e..fecd108c923 100644 --- a/src/Simulation/Simulators/FindNuspecReferences.ps1 +++ b/src/Simulation/Simulators.Core/FindNuspecReferences.ps1 @@ -7,7 +7,7 @@ # This is problematic because we currently don't want to create a package for every dll. # # On the other hand, when creating a package using nuget pack, nuget does not -# identifies PackageReferences defined in the csproj, so all the dependencies +# identify PackageReferences defined in the csproj, so all the dependencies # are not listed and the package doesn't work. # # We don't want to hardcode the list of dependencies on the .nuspec, as they can @@ -97,7 +97,7 @@ function Add-NuGetDependencyFromCsprojToNuspec($PathToCsproj) # Find all dependencies packaged as part of Microsoft.Quantum.Simulators Add-NuGetDependencyFromCsprojToNuspec "../QCTraceSimulator/Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.csproj" # has a dependency on Common, need to list this because it is listed only in an imported props file ... -Add-NuGetDependencyFromCsprojToNuspec "../Simulators/Microsoft.Quantum.Simulators.csproj" +Add-NuGetDependencyFromCsprojToNuspec "Microsoft.Quantum.Simulators.csproj" # Save into .nuspec file: $nuspec.package.metadata.AppendChild($dep) diff --git a/src/Simulation/Simulators/Microsoft.Quantum.Simulators.csproj b/src/Simulation/Simulators.Core/Microsoft.Quantum.Simulators.csproj similarity index 79% rename from src/Simulation/Simulators/Microsoft.Quantum.Simulators.csproj rename to src/Simulation/Simulators.Core/Microsoft.Quantum.Simulators.csproj index ef8c2bb42b6..164ad344852 100644 --- a/src/Simulation/Simulators/Microsoft.Quantum.Simulators.csproj +++ b/src/Simulation/Simulators.Core/Microsoft.Quantum.Simulators.csproj @@ -15,6 +15,14 @@ enable + + + + + + + + diff --git a/src/Simulation/Simulators/Microsoft.Quantum.Simulators.nuspec.template b/src/Simulation/Simulators.Core/Microsoft.Quantum.Simulators.nuspec.template similarity index 64% rename from src/Simulation/Simulators/Microsoft.Quantum.Simulators.nuspec.template rename to src/Simulation/Simulators.Core/Microsoft.Quantum.Simulators.nuspec.template index a6b1ee3819e..3335cefd51b 100644 --- a/src/Simulation/Simulators/Microsoft.Quantum.Simulators.nuspec.template +++ b/src/Simulation/Simulators.Core/Microsoft.Quantum.Simulators.nuspec.template @@ -20,12 +20,12 @@ - - - - - - + + + + + + diff --git a/src/Simulation/Simulators/Properties/AssemblyInfo.cs b/src/Simulation/Simulators.Core/Properties/AssemblyInfo.cs similarity index 100% rename from src/Simulation/Simulators/Properties/AssemblyInfo.cs rename to src/Simulation/Simulators.Core/Properties/AssemblyInfo.cs diff --git a/src/Simulation/Simulators.Tests/Circuits/VerifyUnitary.qs b/src/Simulation/Simulators.Tests/Circuits/VerifyUnitary.qs index e44783a32d6..afde45b0c3b 100644 --- a/src/Simulation/Simulators.Tests/Circuits/VerifyUnitary.qs +++ b/src/Simulation/Simulators.Tests/Circuits/VerifyUnitary.qs @@ -6,7 +6,7 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits { open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Math; open Microsoft.Quantum.Diagnostics; - open Microsoft.Quantum.Simulation.TestSuite; + open Microsoft.Quantum.Measurement; /// @@ -20,7 +20,7 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits { /// then it tests Controlled with different number of control qubits, also verifying that /// Adjoint Controlled works. /// - operation VerifyUnitary (gate : (Qubit => Unit : Adjoint, Controlled), start : (Pauli, Result), expected : (Complex, Complex)) : Unit { + operation VerifyUnitary (gate : (Qubit => Unit is Adj + Ctl), start : (Pauli, Result), expected : (Complex, Complex)) : Unit { using (qubits = Qubit[1]) { @@ -28,14 +28,14 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits { let q1 = qubits[0]; let (a, b) = expected; let (p, r) = start; - SetQubit(r, q1); + SetToBasisState(r, q1); if (p == PauliX) { H(q1); } // Make sure we start in correct state. - Assert([p], [q1], r, $"Qubit in invalid state."); + AssertMeasurement([p], [q1], r, $"Qubit in invalid state."); // Apply the gate, make sure it's in the right state gate(q1); @@ -43,7 +43,7 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits { // Apply Adjoint, back to Zero: Adjoint gate(q1); - Assert([p], [q1], r, $"Qubit in invalid state."); + AssertMeasurement([p], [q1], r, $"Qubit in invalid state."); // When no control qubits, it should be equivalent to just calling the gate: Controlled gate(new Qubit[0], q1); @@ -51,7 +51,7 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits { // Apply Adjoint, back to Zero: Controlled (Adjoint gate)(new Qubit[0], q1); - Assert([p], [q1], r, $"Qubit in invalid state."); + AssertMeasurement([p], [q1], r, $"Qubit in invalid state."); // Now test control... We'll have 3 control qubits. // We will run the test with 1..3 controls at a time. @@ -62,18 +62,18 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits { for (i in 0 .. ctrlsCount - 1) { // We're starting fresh - Assert([p], [q1], r, $"Qubit in invalid state."); + AssertMeasurement([p], [q1], r, $"Qubit in invalid state."); // Get a subset for control and initialize them to zero: let c = ctrls[0 .. i]; for (j in 0 .. i) { - SetQubit(Zero, c[j]); + SetToBasisState(Zero, c[j]); } // Noop when ctrls are all zero. Controlled gate(c, q1); - Assert([p], [q1], r, $"Qubit in invalid state."); + AssertMeasurement([p], [q1], r, $"Qubit in invalid state."); // turn on each of the controls one by one for (j in 1 .. Length(c)) { @@ -85,7 +85,7 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits { AssertQubitIsInStateWithinTolerance(expected, q1, tolerance); } else { - Assert([p], [q1], r, $"Qubit in invalid state."); + AssertMeasurement([p], [q1], r, $"Qubit in invalid state."); } Adjoint Controlled gate(c, q1); @@ -96,8 +96,8 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits { } // We're back where we started. - Assert([p], [q1], r, $"Qubit in invalid state."); - SetQubit(r, q1); + AssertMeasurement([p], [q1], r, $"Qubit in invalid state."); + SetToBasisState(r, q1); ResetAll(qubits); } } diff --git a/src/Simulation/Simulators.Tests/DebuggingToolsTests.cs b/src/Simulation/Simulators.Tests/DebuggingToolsTests.cs index 279a6185f00..0ef42022ab6 100644 --- a/src/Simulation/Simulators.Tests/DebuggingToolsTests.cs +++ b/src/Simulation/Simulators.Tests/DebuggingToolsTests.cs @@ -23,7 +23,7 @@ public void ToStringTests() => Helper.RunWithMultipleSimulators(qsim => { var _ = AbstractCallable._; - var dump = qsim.Get(typeof(Microsoft.Quantum.Extensions.Diagnostics.DumpMachine<>)); + var dump = qsim.Get(typeof(Microsoft.Quantum.Diagnostics.DumpMachine<>)); var trace = qsim.Get(typeof(Circuits.Generics.Trace<>)); var x = qsim.Get(); var q2 = new FreeQubit(2) as Qubit; @@ -223,7 +223,7 @@ public void GenericDebuggerProxy() { Helper.RunWithMultipleSimulators((qsim) => { - var dump = qsim.Get(typeof(Microsoft.Quantum.Extensions.Diagnostics.DumpMachine<>)) as GenericCallable; + var dump = qsim.Get(typeof(Microsoft.Quantum.Diagnostics.DumpMachine<>)) as GenericCallable; var trace = qsim.Get(typeof(Circuits.Generics.Trace<>)) as GenericCallable; var gen3 = qsim.Get(typeof(Circuits.Generics.Gen3<,,>)) as GenericCallable; @@ -231,7 +231,7 @@ public void GenericDebuggerProxy() TestOneProxy("Trace", "Microsoft.Quantum.Simulation.Simulators.Tests.Circuits.Generics.Trace", OperationFunctor.Adjoint, "T => () : Adjoint, Controlled", trace.Adjoint); TestOneProxy("Trace", "Microsoft.Quantum.Simulation.Simulators.Tests.Circuits.Generics.Trace", OperationFunctor.Controlled, "(Qubit[],T) => () : Adjoint, Controlled", trace.Controlled); TestOneProxy("Trace", "Microsoft.Quantum.Simulation.Simulators.Tests.Circuits.Generics.Trace", OperationFunctor.ControlledAdjoint, "(Qubit[],T) => () : Adjoint, Controlled", trace.Adjoint.Controlled); - TestOneProxy("DumpMachine", "Microsoft.Quantum.Extensions.Diagnostics.DumpMachine", OperationFunctor.Body, "T => ()", dump); + TestOneProxy("DumpMachine", "Microsoft.Quantum.Diagnostics.DumpMachine", OperationFunctor.Body, "T => ()", dump); TestOneProxy("Gen3", "Microsoft.Quantum.Simulation.Simulators.Tests.Circuits.Generics.Gen3", OperationFunctor.Body, "(__T1,(__T2,__T3),Result) => () : Controlled", gen3); TestOneProxy("Gen3", "Microsoft.Quantum.Simulation.Simulators.Tests.Circuits.Generics.Gen3", OperationFunctor.Controlled, "(Qubit[],(__T1,(__T2,__T3),Result)) => () : Controlled", gen3.Controlled); }); @@ -252,7 +252,7 @@ public void GenericPartialDebuggerProxy() { var _ = AbstractCallable._; - var dump = qsim.Get(typeof(Microsoft.Quantum.Extensions.Diagnostics.DumpMachine<>)) as GenericCallable; + var dump = qsim.Get(typeof(Microsoft.Quantum.Diagnostics.DumpMachine<>)) as GenericCallable; var trace = qsim.Get(typeof(Circuits.Generics.Trace<>)) as GenericCallable; var gen3 = qsim.Get(typeof(Circuits.Generics.Gen3<,,>)) as GenericCallable; diff --git a/src/Simulation/Simulators.Tests/OperationsTestHelper.cs b/src/Simulation/Simulators.Tests/OperationsTestHelper.cs index 7fa82ca1077..9f3febb14bb 100644 --- a/src/Simulation/Simulators.Tests/OperationsTestHelper.cs +++ b/src/Simulation/Simulators.Tests/OperationsTestHelper.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using Microsoft.Quantum.Simulation.Common; using Microsoft.Quantum.Simulation.Core; @@ -14,6 +13,18 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests { + public static class Extensions + { + /// + /// This method is a wrapper to let the tests keep using a one Type parameter + /// method to fetch for Gates. + /// + public static T Get(this SimulatorBase sim) where T : AbstractCallable + { + return sim.Get(); + } + } + public class Log { public Dictionary _log = new Dictionary(); @@ -88,75 +99,8 @@ private void OnStart(ICallable arg1, IApplyData arg2) } } - static class OperationsTestHelper + static partial class OperationsTestHelper { - public static TraceImpl GetTracer(this SimulatorBase s) - { - return s.Get(typeof(Tests.Circuits.Generics.Trace<>)).FindCallable(typeof(T), typeof(QVoid)) as TraceImpl; - } - - - public class TracerImpl : Tests.Circuits.ClosedType.Trace - { - public TracerImpl(IOperationFactory m) : base(m) - { - this.Log = new Log(); - } - - public override Func Body => (tag) => this.Log.Record(OperationFunctor.Body, tag); - public override Func AdjointBody => (tag) => this.Log.Record(OperationFunctor.Adjoint, tag); - public override Func<(IQArray, string), QVoid> ControlledBody => (args) => this.Log.Record(OperationFunctor.Controlled, args.Item2); - public override Func<(IQArray, string), QVoid> ControlledAdjointBody => (args) => this.Log.Record(OperationFunctor.ControlledAdjoint, args.Item2); - - public Log Log { get; } - } - - public class TraceImpl : Tests.Circuits.Generics.Trace - { - public TraceImpl(IOperationFactory m) : base(m) - { - this.Log = new Log(); - } - - public override Func Body => (tag) => this.Log.Record(OperationFunctor.Body, tag); - public override Func AdjointBody => (tag) => this.Log.Record(OperationFunctor.Adjoint, tag); - public override Func<(IQArray, T), QVoid> ControlledBody => (args) => this.Log.Record(OperationFunctor.Controlled, args.Item2); - public override Func<(IQArray, T), QVoid> ControlledAdjointBody => (args) => this.Log.Record(OperationFunctor.ControlledAdjoint, args.Item2); - - public int GetNumberOfCalls(OperationFunctor functor, T tag) => this.Log.GetNumberOfCalls(functor, tag); - - public Log Log { get; } - } - - private static void InitSimulator(SimulatorBase sim) - { - sim.InitBuiltinOperations(typeof(OperationsTestHelper)); - sim.Register(typeof(Tests.Circuits.Generics.Trace<>), typeof(TraceImpl<>), typeof(IUnitary)); - - // For Toffoli, replace H with I. - if (sim is ToffoliSimulator) - { - sim.Register(typeof(Intrinsic.H), typeof(Intrinsic.I), typeof(IUnitary)); - } - } - - public static void RunWithMultipleSimulators(Action test) - { - var simulators = new SimulatorBase[] { new QuantumSimulator(), new ToffoliSimulator() }; - - foreach (var s in simulators) - { - InitSimulator(s); - - test(s); - - if (s is IDisposable sim) - { - sim.Dispose(); - } - } - } - /// /// A shell for simple Apply tests. /// @@ -189,13 +133,13 @@ internal static void ctrlErrorConditionsTests(SimulatorBase sim, Action<(IQArray /// /// A shell for simple Controlled tests. It calls the controlled operation with 0..4 control qubits - /// set to all possible combination of 1 & 0. + /// set to all possible combination of 1 and 0. /// internal static void ctrlTestShell(SimulatorBase sim, Action<(IQArray, Qubit)> operationControlled, Action, Qubit> test) { var allocate = sim.Get(); var release = sim.Get(); - var set = sim.Get(); + var set = sim.Get(); // Number of control bits to use for (int n = 0; n < 4; n++) diff --git a/src/Simulation/Simulators.Tests/OperationsTestHelperSimSupport.cs b/src/Simulation/Simulators.Tests/OperationsTestHelperSimSupport.cs new file mode 100644 index 00000000000..477571f7024 --- /dev/null +++ b/src/Simulation/Simulators.Tests/OperationsTestHelperSimSupport.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using Microsoft.Quantum.Simulation.Common; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.Simulators.Tests +{ + static partial class OperationsTestHelper + { + private static void InitSimulator(SimulatorBase sim) + { + sim.InitBuiltinOperations(typeof(OperationsTestHelper)); + sim.Register(typeof(Tests.Circuits.Generics.Trace<>), typeof(TraceImpl<>), typeof(IUnitary)); + + // For Toffoli, replace H with I. + if (sim is ToffoliSimulator) + { + sim.Register(typeof(Intrinsic.H), typeof(Intrinsic.I), typeof(IUnitary)); + } + } + + public static void RunWithMultipleSimulators(Action test) + { + var simulators = new SimulatorBase[] { new QuantumSimulator(), new ToffoliSimulator() }; + + foreach (var s in simulators) + { + InitSimulator(s); + + test(s); + + if (s is IDisposable sim) + { + sim.Dispose(); + } + } + } + } +} \ No newline at end of file diff --git a/src/Simulation/Simulators.Tests/QuantumSimulatorTests/BasicTests.cs b/src/Simulation/Simulators.Tests/QuantumSimulatorTests/BasicTests.cs index 092106269f0..64bb4ec919c 100644 --- a/src/Simulation/Simulators.Tests/QuantumSimulatorTests/BasicTests.cs +++ b/src/Simulation/Simulators.Tests/QuantumSimulatorTests/BasicTests.cs @@ -7,7 +7,6 @@ using System.Threading.Tasks; using Microsoft.Quantum.Simulation.Core; using Microsoft.Quantum.Simulation.Simulators.Exceptions; -using Microsoft.Quantum.Simulation.Simulators.Tests.Circuits; using Xunit; namespace Microsoft.Quantum.Simulation.Simulators.Tests @@ -60,7 +59,7 @@ public void QSimX() { var x = sim.Get(); var measure = sim.Get(); - var set = sim.Get(); + var set = sim.Get(); var ctrlX = x.ControlledBody.AsAction(); OperationsTestHelper.ctrlTestShell(sim, ctrlX, (enabled, ctrls, q) => diff --git a/src/Simulation/Simulators.Tests/QuantumSimulatorTests/VerifyGates.cs b/src/Simulation/Simulators.Tests/QuantumSimulatorTests/VerifyGates.cs index 0cc32328fdf..7b1b652e6cc 100644 --- a/src/Simulation/Simulators.Tests/QuantumSimulatorTests/VerifyGates.cs +++ b/src/Simulation/Simulators.Tests/QuantumSimulatorTests/VerifyGates.cs @@ -2,7 +2,6 @@ // Licensed under the MIT License. using System; -using System.Threading.Tasks; using Microsoft.Quantum.Simulation.Core; using Microsoft.Quantum.Simulation.Simulators.Tests.Circuits; using Xunit; diff --git a/src/Simulation/Simulators.Tests/ResourcesEstimatorTests.cs b/src/Simulation/Simulators.Tests/ResourcesEstimatorTests.cs index 0a60328484d..ce7d93c855f 100644 --- a/src/Simulation/Simulators.Tests/ResourcesEstimatorTests.cs +++ b/src/Simulation/Simulators.Tests/ResourcesEstimatorTests.cs @@ -99,8 +99,8 @@ public void ToTSVTest() var cliffords = rows.First(r => r.StartsWith("QubitClifford")).Split('\t'); Assert.Equal(3, cliffords.Length); Assert.Equal("2", cliffords[1]); - } - + } + /// /// Shows that T gates on different qubits are counted for depth purposes as /// executing in parallel. @@ -117,8 +117,8 @@ public void DepthDifferentQubitsTest() Assert.Equal(4.0, data.Rows.Find("T")["Sum"]); Assert.Equal(3.0, data.Rows.Find("Width")["Sum"]); Assert.Equal(2.0, data.Rows.Find("Depth")["Sum"]); - } - + } + /// /// Documents that the width and depth statistics reflect independent lower /// bounds for each (two T gates cannot be combined into a circuit of depth diff --git a/src/Simulation/Simulators.Tests/SimulatorBaseTests.cs b/src/Simulation/Simulators.Tests/SimulatorBaseTests.cs index f9b73e477e9..48ee362dc99 100644 --- a/src/Simulation/Simulators.Tests/SimulatorBaseTests.cs +++ b/src/Simulation/Simulators.Tests/SimulatorBaseTests.cs @@ -10,18 +10,6 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests { - public static class Extensions - { - /// - /// This method is a wrapper to let the tests keep using a one Type parameter - /// method to fetch for Gates. - /// - public static T Get(this SimulatorBase sim) where T : AbstractCallable - { - return sim.Get(); - } - } - public class SimulatorBaseTests { private readonly ITestOutputHelper output; diff --git a/src/Simulation/Simulators.Tests/TestProjects/IntrinsicTests/IntrinsicTests.csproj b/src/Simulation/Simulators.Tests/TestProjects/IntrinsicTests/IntrinsicTests.csproj index 71bd465814e..0fae894e16a 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/IntrinsicTests/IntrinsicTests.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/IntrinsicTests/IntrinsicTests.csproj @@ -3,7 +3,6 @@ netcoreapp3.1 false - true false false @@ -11,8 +10,7 @@ - - + diff --git a/src/Simulation/Simulators.Tests/TestProjects/TargetedExe/TargetedExe.csproj b/src/Simulation/Simulators.Tests/TestProjects/TargetedExe/TargetedExe.csproj index b8f0258e5c2..e0d76a09805 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/TargetedExe/TargetedExe.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/TargetedExe/TargetedExe.csproj @@ -13,7 +13,6 @@ - diff --git a/src/Simulation/Simulators.Tests/TestProjects/UnitTests/Hello.qs b/src/Simulation/Simulators.Tests/TestProjects/UnitTests/Hello.qs index 8e5d87f77a8..4d8cd71c3b1 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/UnitTests/Hello.qs +++ b/src/Simulation/Simulators.Tests/TestProjects/UnitTests/Hello.qs @@ -1,16 +1,16 @@ -// Used for a unit test; -// do not change the name of this namespace! -namespace Microsoft.Quantum.Library { - - open Microsoft.Quantum.Intrinsic; - - // Used for a unit test; - // do not change the name or namespace of this type! - newtype Token = Unit; - - // Used for a unit test; - // do not change the name or namespace of this callable! - operation Hello(dummy : Token) : Unit { - Message("Hello!"); - } +// Used for a unit test; +// do not change the name of this namespace! +namespace Microsoft.Quantum.Library { + + open Microsoft.Quantum.Intrinsic; + + // Used for a unit test; + // do not change the name or namespace of this type! + newtype Token = Unit; + + // Used for a unit test; + // do not change the name or namespace of this callable! + operation Hello(dummy : Token) : Unit { + Message("Hello!"); + } } \ No newline at end of file diff --git a/src/Simulation/Simulators.Tests/TestProjects/UnitTests/UnitTests.csproj b/src/Simulation/Simulators.Tests/TestProjects/UnitTests/UnitTests.csproj index 7cc66e81104..ad0471edaec 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/UnitTests/UnitTests.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/UnitTests/UnitTests.csproj @@ -11,8 +11,7 @@ - - + diff --git a/src/Simulation/Simulators.Tests/TracerHelper.cs b/src/Simulation/Simulators.Tests/TracerHelper.cs new file mode 100644 index 00000000000..73437a32ec5 --- /dev/null +++ b/src/Simulation/Simulators.Tests/TracerHelper.cs @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using Microsoft.Quantum.Simulation.Common; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.Simulators.Tests +{ + static partial class OperationsTestHelper + { + public static TraceImpl GetTracer(this SimulatorBase s) + { + return s.Get(typeof(Tests.Circuits.Generics.Trace<>)).FindCallable(typeof(T), typeof(QVoid)) as TraceImpl; + } + + + public class TracerImpl : Tests.Circuits.ClosedType.Trace + { + public TracerImpl(IOperationFactory m) : base(m) + { + this.Log = new Log(); + } + + public override Func Body => (tag) => this.Log.Record(OperationFunctor.Body, tag); + public override Func AdjointBody => (tag) => this.Log.Record(OperationFunctor.Adjoint, tag); + public override Func<(IQArray, string), QVoid> ControlledBody => (args) => this.Log.Record(OperationFunctor.Controlled, args.Item2); + public override Func<(IQArray, string), QVoid> ControlledAdjointBody => (args) => this.Log.Record(OperationFunctor.ControlledAdjoint, args.Item2); + + public Log Log { get; } + } + + public class TraceImpl : Tests.Circuits.Generics.Trace + { + public TraceImpl(IOperationFactory m) : base(m) + { + this.Log = new Log(); + } + + public override Func Body => (tag) => this.Log.Record(OperationFunctor.Body, tag); + public override Func AdjointBody => (tag) => this.Log.Record(OperationFunctor.Adjoint, tag); + public override Func<(IQArray, T), QVoid> ControlledBody => (args) => this.Log.Record(OperationFunctor.Controlled, args.Item2); + public override Func<(IQArray, T), QVoid> ControlledAdjointBody => (args) => this.Log.Record(OperationFunctor.ControlledAdjoint, args.Item2); + + public int GetNumberOfCalls(OperationFunctor functor, T tag) => this.Log.GetNumberOfCalls(functor, tag); + + public Log Log { get; } + } + + } +} \ No newline at end of file diff --git a/src/Simulation/Simulators.Type2.Tests/App.config b/src/Simulation/Simulators.Type2.Tests/App.config new file mode 100644 index 00000000000..94ce1a2b94f --- /dev/null +++ b/src/Simulation/Simulators.Type2.Tests/App.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/Simulation/Simulators.Type2.Tests/OperationsTestHelperSimSupport.cs b/src/Simulation/Simulators.Type2.Tests/OperationsTestHelperSimSupport.cs new file mode 100644 index 00000000000..d6abcc6ed50 --- /dev/null +++ b/src/Simulation/Simulators.Type2.Tests/OperationsTestHelperSimSupport.cs @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using Microsoft.Quantum.Simulation.Common; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.Simulators.Tests +{ + static partial class OperationsTestHelper + { + private static void InitSimulator(SimulatorBase sim) + { + sim.InitBuiltinOperations(typeof(OperationsTestHelper)); + } + + public static void RunWithMultipleSimulators(Action test) + { + var simulators = new SimulatorBase[] { new QuantumSimulator() }; + + foreach (var s in simulators) + { + InitSimulator(s); + + test(s); + + if (s is IDisposable sim) + { + sim.Dispose(); + } + } + } + } +} \ No newline at end of file diff --git a/src/Simulation/Simulators.Type2.Tests/Tests.Microsoft.Quantum.Simulators.Type2.csproj b/src/Simulation/Simulators.Type2.Tests/Tests.Microsoft.Quantum.Simulators.Type2.csproj new file mode 100644 index 00000000000..22586d82c91 --- /dev/null +++ b/src/Simulation/Simulators.Type2.Tests/Tests.Microsoft.Quantum.Simulators.Type2.csproj @@ -0,0 +1,57 @@ + + + + + + + + netcoreapp3.1 + false + false + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ExeDir>$(MSBuildThisFileDirectory)TestProjects\QsharpExe\built\ + <_TargetedExeDir>$(MSBuildThisFileDirectory)TestProjects\TargetedExe\built\ + + + <_ExeFiles Include="$(_ExeDir)*" /> + <_TargetedExeFiles Include="$(_TargetedExeDir)*" /> + + + + + + + + + + diff --git a/src/Simulation/Simulators.Type2/.gitignore b/src/Simulation/Simulators.Type2/.gitignore new file mode 100644 index 00000000000..a9a143aa9ce --- /dev/null +++ b/src/Simulation/Simulators.Type2/.gitignore @@ -0,0 +1 @@ +Microsoft.Quantum.Simulators.Type2.nuspec \ No newline at end of file diff --git a/src/Simulation/Simulators.Type2/FindNuspecReferences.ps1 b/src/Simulation/Simulators.Type2/FindNuspecReferences.ps1 new file mode 100644 index 00000000000..3c86d876ef3 --- /dev/null +++ b/src/Simulation/Simulators.Type2/FindNuspecReferences.ps1 @@ -0,0 +1,103 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +######################################## +# When creating a package with dotnet pack, nuget changes every ProjectReference to be itself +# a PackageReference (without checking if that project has a corresponding package). +# This is problematic because we currently don't want to create a package for every dll. +# +# On the other hand, when creating a package using nuget pack, nuget does not +# identify PackageReferences defined in the csproj, so all the dependencies +# are not listed and the package doesn't work. +# +# We don't want to hardcode the list of dependencies on the .nuspec, as they can +# quickly become out-of-sync. +# This script will find the PackageReferences recursively on the simulation projects and add them +# to the nuspec, so we can then create the package using nuget pack with the corresponding +# dependencies listed. +# +# nuget is tracking this problem at: https://github.com/NuGet/Home/issues/4491 +######################################## + +$target = Join-Path $PSScriptRoot "Microsoft.Quantum.Simulators.Type2.nuspec" + +if (Test-Path $target) { + Write-Host "$target exists. Skipping generating new one." + exit + } + + +# Start with the nuspec template +$nuspec = [xml](Get-Content (Join-Path $PSScriptRoot "Microsoft.Quantum.Simulators.Type2.nuspec.template")) +$dep = $nuspec.CreateElement('dependencies', $nuspec.package.metadata.NamespaceURI) + +function Add-PackageReferenceIfNew($ref) +{ + # Identify package's id either from "Include" or "Update" attribute: + $id = $ref.Include + $version = $ref.Version + + if ($id -eq $null -or $id -eq "") { + $id = $ref.Update + } + if ($id.EndsWith('.csproj') -or $id.EndsWith('.fsproj')) + { + $id = [System.IO.Path]::GetFileNameWithoutExtension($id) + } + + if ($version -eq $null -or $version -eq "") { + $version = '$version$' + } + + # Check if package already added as dependency, only add if new: + $added = $dep.dependency | Where { $_.id -eq $id } + if (!$added) { + Write-Host "Adding $id (version: $version)" + $onedependency = $dep.AppendChild($nuspec.CreateElement('dependency', $nuspec.package.metadata.NamespaceURI)) + $onedependency.SetAttribute('id', $id) + $onedependency.SetAttribute('version', $version) + } +} + +# Recursively find PackageReferences on all ProjectReferences: +function Add-NuGetDependencyFromCsprojToNuspec($PathToCsproj) +{ + Write-Host "`nFinding dependencies for $PathToCsproj" + $csproj = [xml](Get-Content $PathToCsproj) + + # Find all PackageReferences nodes: + $packageDependency = $csproj.Project.ItemGroup.PackageReference | Where-Object { $null -ne $_ } + $packageDependency | ForEach-Object { + $id = $_.Include + Write-Host "Detected package dependencies: $id" + } + + $packageDependency | ForEach-Object { + Add-PackageReferenceIfNew $_ + } + + $projectDependency = $csproj.Project.ItemGroup.ProjectReference | Where-Object { $null -ne $_ } + $projectDependency | ForEach-Object { + $id = $_.Include + Write-Host "Detected project dependencies: $id" + } + + # Assume there is a package for project references that are not tagged as to be included in the simulator package: + $projectDependency | Where-Object {$_.IncludeInSimulatorPackage -ne 'true' -and $_.IsQscReference -ne 'true'} | ForEach-Object { + Add-PackageReferenceIfNew $_ + } + + # Recursively check on project references if they are private: + $projectDependency | Where-Object {$_.IncludeInSimulatorPackage -eq 'true' -and $_.IsQscReference -ne 'true'} | ForEach-Object { + $id = $_.Include + Write-Host "Recurring for $id" + Add-NuGetDependencyFromCsprojToNuspec $_.Include + } +} + +# Find all dependencies packaged as part of Microsoft.Quantum.Simulators.Type2 +Add-NuGetDependencyFromCsprojToNuspec "Microsoft.Quantum.Simulators.Type2.csproj" + +# Save into .nuspec file: +$nuspec.package.metadata.AppendChild($dep) +$nuspec.Save($target) diff --git a/src/Simulation/Simulators.Type2/Microsoft.Quantum.Simulators.Type2.csproj b/src/Simulation/Simulators.Type2/Microsoft.Quantum.Simulators.Type2.csproj new file mode 100644 index 00000000000..a10fef46f36 --- /dev/null +++ b/src/Simulation/Simulators.Type2/Microsoft.Quantum.Simulators.Type2.csproj @@ -0,0 +1,42 @@ + + + + + + + + netstandard2.1 + + + + 8.0 + enable + + + + + + + + + + + + + runtimes\win-x64\native\%(RecursiveDir)%(FileName)%(Extension) + PreserveNewest + false + + + runtimes\osx-x64\native\%(RecursiveDir)%(FileName)%(Extension) + PreserveNewest + false + + + runtimes\linux-x64\native\%(RecursiveDir)%(FileName)%(Extension) + PreserveNewest + false + + + + diff --git a/src/Simulation/Simulators.Type2/Microsoft.Quantum.Simulators.Type2.nuspec.template b/src/Simulation/Simulators.Type2/Microsoft.Quantum.Simulators.Type2.nuspec.template new file mode 100644 index 00000000000..0259a979f74 --- /dev/null +++ b/src/Simulation/Simulators.Type2/Microsoft.Quantum.Simulators.Type2.nuspec.template @@ -0,0 +1,31 @@ + + + + Microsoft.Quantum.Simulators + $version$ + $title$ + Microsoft + QuantumEngineering, Microsoft + MIT + https://docs.microsoft.com/en-us/quantum + images\qdk-nuget-icon.png + false + Type2 simulators of quantum computers for the Q# programming language. + See: https://docs.microsoft.com/en-us/quantum/relnotes/ + © Microsoft Corporation. All rights reserved. + Quantum Q# Qsharp + + + + + + + + + + + + + + + diff --git a/src/Simulation/Simulators.Type2/Properties/AssemblyInfo.cs b/src/Simulation/Simulators.Type2/Properties/AssemblyInfo.cs new file mode 100644 index 00000000000..a11422cdc41 --- /dev/null +++ b/src/Simulation/Simulators.Type2/Properties/AssemblyInfo.cs @@ -0,0 +1,9 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Allow the test assembly to use our internal methods +[assembly: InternalsVisibleTo("Tests.Microsoft.Quantum.Simulators.Type2" + SigningConstants.PUBLIC_KEY)] \ No newline at end of file diff --git a/src/Simulation/Simulators/QCTraceSimulator/Circuits/Primitive.IsingXX.qs b/src/Simulation/Simulators/QCTraceSimulator/Circuits/Primitive.IsingXX.qs new file mode 100644 index 00000000000..5f75f95fb02 --- /dev/null +++ b/src/Simulation/Simulators/QCTraceSimulator/Circuits/Primitive.IsingXX.qs @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators.Circuits { + operation IsingXX (theta : Double, qubit0 : Qubit, qubit1 : Qubit) : Unit is Adj + Ctl { + Exp([PauliX, PauliX], theta * 2.0, [qubit0, qubit1]); + } +} \ No newline at end of file diff --git a/src/Simulation/Simulators/QCTraceSimulator/Circuits/Primitive.IsingYY.qs b/src/Simulation/Simulators/QCTraceSimulator/Circuits/Primitive.IsingYY.qs new file mode 100644 index 00000000000..9315f86ef86 --- /dev/null +++ b/src/Simulation/Simulators/QCTraceSimulator/Circuits/Primitive.IsingYY.qs @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators.Circuits { + operation IsingYY (theta : Double, qubit0 : Qubit, qubit1 : Qubit) : Unit is Adj + Ctl { + Exp([PauliY, PauliY], theta * 2.0, [qubit0, qubit1]); + } +} \ No newline at end of file diff --git a/src/Simulation/Simulators/QCTraceSimulator/Circuits/Primitive.IsingZZ.qs b/src/Simulation/Simulators/QCTraceSimulator/Circuits/Primitive.IsingZZ.qs new file mode 100644 index 00000000000..c6f7a753326 --- /dev/null +++ b/src/Simulation/Simulators/QCTraceSimulator/Circuits/Primitive.IsingZZ.qs @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators.Circuits { + operation IsingZZ (theta : Double, qubit0 : Qubit, qubit1 : Qubit) : Unit is Adj + Ctl { + Exp([PauliZ, PauliZ], theta * 2.0, [qubit0, qubit1]); + } +} \ No newline at end of file diff --git a/src/Simulation/Simulators/QCTraceSimulator/QCTraceSimulator.Checks.cs b/src/Simulation/Simulators/QCTraceSimulator/QCTraceSimulator.Checks.cs new file mode 100644 index 00000000000..af798f924c4 --- /dev/null +++ b/src/Simulation/Simulators/QCTraceSimulator/QCTraceSimulator.Checks.cs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators.Implementation +{ + public partial class QCTraceSimulatorImpl + { + public class QCTracesimulatorImplCheckQubitUniqueness : Intrinsic.CheckQubitUniqueness + { + public QCTracesimulatorImplCheckQubitUniqueness(QCTraceSimulatorImpl m) : base(m) + { + } + + public override Func, QVoid> Body => (qubits) => + { + // Noop + return QVoid.Instance; + }; + + public override Func<(IQArray, IQArray), QVoid> ControlledBody => (args) => + { + // Noop + return QVoid.Instance; + }; + } + + public class QCTracesimulatorImplRotationAngleValidation : Intrinsic.RotationAngleValidation + { + public QCTracesimulatorImplRotationAngleValidation(QCTraceSimulatorImpl m) : base(m) + { + } + + public override Func Body => (angle) => + { + // Noop + return QVoid.Instance; + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumSimulator/Checks.cs b/src/Simulation/Simulators/QuantumSimulator/Checks.cs new file mode 100644 index 00000000000..040c2161837 --- /dev/null +++ b/src/Simulation/Simulators/QuantumSimulator/Checks.cs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.Simulators +{ + public partial class QuantumSimulator + { + public class QSimCheckQubitUniqueness : Intrinsic.CheckQubitUniqueness + { + private QuantumSimulator Simulator { get; } + public QSimCheckQubitUniqueness(QuantumSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func, QVoid> Body => (qubits) => + { + Simulator.CheckQubits(qubits); + return QVoid.Instance; + }; + + public override Func<(IQArray, IQArray), QVoid> ControlledBody => (args) => + { + var (ctrls, qubits) = args; + Simulator.CheckQubits(QArray.Add(ctrls, qubits)); + return QVoid.Instance; + }; + } + + public class QSimRotationAngleValidation : Intrinsic.RotationAngleValidation + { + public QSimRotationAngleValidation(QuantumSimulator m) : base(m) + { + } + + public override Func Body => (angle) => + { + CheckAngle(angle); + return QVoid.Instance; + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumSimulator/ExpFrac.cs b/src/Simulation/Simulators/QuantumSimulator/ExpFrac.cs deleted file mode 100644 index cc1a18b25a6..00000000000 --- a/src/Simulation/Simulators/QuantumSimulator/ExpFrac.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; - -using Microsoft.Quantum.Simulation.Core; - -namespace Microsoft.Quantum.Simulation.Simulators -{ - - public partial class QuantumSimulator - { - public class QSimExpFrac : Intrinsic.ExpFrac - { - public QSimExpFrac(QuantumSimulator m) : base(m) - { - } - - public static double Angle(long numerator, long power) => - (System.Math.PI * numerator) / (1 << (int)power); - - public override Func<(IQArray, long, long, IQArray), QVoid> Body => (args) => - { - var (paulis, numerator, power, qubits) = args; - var angle = Angle(numerator, power); - return Exp.Apply((paulis, angle, qubits)); - }; - - public override Func<(IQArray, long, long, IQArray), QVoid> AdjointBody => (args) => - { - var (paulis, numerator, power, qubits) = args; - var angle = Angle(numerator, power); - return Exp.Adjoint.Apply((paulis, angle, qubits)); - }; - - public override Func<(IQArray, (IQArray, long, long, IQArray)), QVoid> ControlledBody => (args) => - { - var (ctrls, (paulis, numerator, power, qubits)) = args; - var angle = Angle(numerator, power); - return Exp.Controlled.Apply((ctrls, (paulis, angle, qubits))); - }; - - public override Func<(IQArray, (IQArray, long, long, IQArray)), QVoid> ControlledAdjointBody => (args) => - { - var (ctrls, (paulis, numerator, power, qubits)) = args; - var angle = Angle(numerator, power); - return Exp.Adjoint.Controlled.Apply((ctrls, (paulis, angle, qubits))); - }; - } - } -} diff --git a/src/Simulation/Common/Extensions.cs b/src/Simulation/Simulators/QuantumSimulator/Extensions.cs similarity index 98% rename from src/Simulation/Common/Extensions.cs rename to src/Simulation/Simulators/QuantumSimulator/Extensions.cs index b36867a7388..d2d098812d0 100644 --- a/src/Simulation/Common/Extensions.cs +++ b/src/Simulation/Simulators/QuantumSimulator/Extensions.cs @@ -44,7 +44,7 @@ from op in t.GetNestedTypes() where op.IsSubclassOf(typeof(T)) select op; - foreach (var op in ops) + foreach (var op in ops.Where(o => o.BaseType.IsAbstract)) { factory.Register(op.BaseType, op); } diff --git a/src/Simulation/Simulators/QuantumSimulator/IsingXX.cs b/src/Simulation/Simulators/QuantumSimulator/IsingXX.cs new file mode 100644 index 00000000000..42aada73c36 --- /dev/null +++ b/src/Simulation/Simulators/QuantumSimulator/IsingXX.cs @@ -0,0 +1,77 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.Simulators +{ + + public partial class QuantumSimulator + { + public class QSimIsingXX : Intrinsic.IsingXX + { + [DllImport(QSIM_DLL_NAME, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, EntryPoint = "Exp")] + private static extern void Exp(uint id, uint n, Pauli[] paulis, double angle, uint[] ids); + + [DllImport(QSIM_DLL_NAME, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, EntryPoint = "MCExp")] + private static extern void MCExp(uint id, uint n, Pauli[] paulis, double angle, uint nc, uint[] ctrls, uint[] ids); + + private QuantumSimulator Simulator { get; } + + public QSimIsingXX(QuantumSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func<(double, Qubit, Qubit), QVoid> Body => (args) => + { + var (angle, qubit1, qubit2) = args; + var paulis = new Pauli[]{ Pauli.PauliX, Pauli.PauliX }; + var targets = new QArray(new Qubit[]{ qubit1, qubit2 }); + CheckAngle(angle); + Simulator.CheckQubits(targets); + + Exp(Simulator.Id, (uint)targets.Length, paulis, angle * 2.0, targets.GetIds()); + + return QVoid.Instance; + }; + + public override Func<(double, Qubit, Qubit), QVoid> AdjointBody => (args) => + { + var (angle, qubit1, qubit2) = args; + + return this.Body.Invoke((-angle, qubit1, qubit2)); + }; + + public override Func<(IQArray, (double, Qubit, Qubit)), QVoid> ControlledBody => (args) => + { + var (ctrls, (angle, qubit1, qubit2)) = args; + + if (ctrls == null || ctrls.Length == 0) + { + this.Body.Invoke((angle, qubit1, qubit2)); + } + else + { + var targets = new QArray(new Qubit[]{ qubit1, qubit2 }); + var paulis = new Pauli[]{ Pauli.PauliX, Pauli.PauliX }; + CheckAngle(angle); + Simulator.CheckQubits(QArray.Add(ctrls, targets)); + + MCExp(Simulator.Id, (uint)targets.Length, paulis, angle * 2.0, (uint)ctrls.Length, ctrls.GetIds(), targets.GetIds()); + } + + return QVoid.Instance; + }; + + public override Func<(IQArray, (double, Qubit, Qubit)), QVoid> ControlledAdjointBody => (args) => + { + var (ctrls, (angle, qubit1, qubit2)) = args; + + return this.ControlledBody.Invoke((ctrls, (-angle, qubit1, qubit2))); + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumSimulator/IsingYY.cs b/src/Simulation/Simulators/QuantumSimulator/IsingYY.cs new file mode 100644 index 00000000000..956c02ff1dc --- /dev/null +++ b/src/Simulation/Simulators/QuantumSimulator/IsingYY.cs @@ -0,0 +1,77 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.Simulators +{ + + public partial class QuantumSimulator + { + public class QSimIsingYY : Intrinsic.IsingYY + { + [DllImport(QSIM_DLL_NAME, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, EntryPoint = "Exp")] + private static extern void Exp(uint id, uint n, Pauli[] paulis, double angle, uint[] ids); + + [DllImport(QSIM_DLL_NAME, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, EntryPoint = "MCExp")] + private static extern void MCExp(uint id, uint n, Pauli[] paulis, double angle, uint nc, uint[] ctrls, uint[] ids); + + private QuantumSimulator Simulator { get; } + + public QSimIsingYY(QuantumSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func<(double, Qubit, Qubit), QVoid> Body => (args) => + { + var (angle, qubit1, qubit2) = args; + var paulis = new Pauli[]{ Pauli.PauliY, Pauli.PauliY }; + var targets = new QArray(new Qubit[]{ qubit1, qubit2 }); + CheckAngle(angle); + Simulator.CheckQubits(targets); + + Exp(Simulator.Id, (uint)targets.Length, paulis, angle * 2.0, targets.GetIds()); + + return QVoid.Instance; + }; + + public override Func<(double, Qubit, Qubit), QVoid> AdjointBody => (args) => + { + var (angle, qubit1, qubit2) = args; + + return this.Body.Invoke((-angle, qubit1, qubit2)); + }; + + public override Func<(IQArray, (double, Qubit, Qubit)), QVoid> ControlledBody => (args) => + { + var (ctrls, (angle, qubit1, qubit2)) = args; + + if (ctrls == null || ctrls.Length == 0) + { + this.Body.Invoke((angle, qubit1, qubit2)); + } + else + { + var targets = new QArray(new Qubit[]{ qubit1, qubit2 }); + var paulis = new Pauli[]{ Pauli.PauliY, Pauli.PauliY }; + CheckAngle(angle); + Simulator.CheckQubits(QArray.Add(ctrls, targets)); + + MCExp(Simulator.Id, (uint)targets.Length, paulis, angle * 2.0, (uint)ctrls.Length, ctrls.GetIds(), targets.GetIds()); + } + + return QVoid.Instance; + }; + + public override Func<(IQArray, (double, Qubit, Qubit)), QVoid> ControlledAdjointBody => (args) => + { + var (ctrls, (angle, qubit1, qubit2)) = args; + + return this.ControlledBody.Invoke((ctrls, (-angle, qubit1, qubit2))); + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumSimulator/IsingZZ.cs b/src/Simulation/Simulators/QuantumSimulator/IsingZZ.cs new file mode 100644 index 00000000000..b7c1f21bd34 --- /dev/null +++ b/src/Simulation/Simulators/QuantumSimulator/IsingZZ.cs @@ -0,0 +1,77 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.Simulators +{ + + public partial class QuantumSimulator + { + public class QSimIsingZZ : Intrinsic.IsingZZ + { + [DllImport(QSIM_DLL_NAME, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, EntryPoint = "Exp")] + private static extern void Exp(uint id, uint n, Pauli[] paulis, double angle, uint[] ids); + + [DllImport(QSIM_DLL_NAME, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, EntryPoint = "MCExp")] + private static extern void MCExp(uint id, uint n, Pauli[] paulis, double angle, uint nc, uint[] ctrls, uint[] ids); + + private QuantumSimulator Simulator { get; } + + public QSimIsingZZ(QuantumSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func<(double, Qubit, Qubit), QVoid> Body => (args) => + { + var (angle, qubit1, qubit2) = args; + var paulis = new Pauli[]{ Pauli.PauliZ, Pauli.PauliZ }; + var targets = new QArray(new Qubit[]{ qubit1, qubit2 }); + CheckAngle(angle); + Simulator.CheckQubits(targets); + + Exp(Simulator.Id, (uint)targets.Length, paulis, angle * 2.0, targets.GetIds()); + + return QVoid.Instance; + }; + + public override Func<(double, Qubit, Qubit), QVoid> AdjointBody => (args) => + { + var (angle, qubit1, qubit2) = args; + + return this.Body.Invoke((-angle, qubit1, qubit2)); + }; + + public override Func<(IQArray, (double, Qubit, Qubit)), QVoid> ControlledBody => (args) => + { + var (ctrls, (angle, qubit1, qubit2)) = args; + + if (ctrls == null || ctrls.Length == 0) + { + this.Body.Invoke((angle, qubit1, qubit2)); + } + else + { + var targets = new QArray(new Qubit[]{ qubit1, qubit2 }); + var paulis = new Pauli[]{ Pauli.PauliZ, Pauli.PauliZ }; + CheckAngle(angle); + Simulator.CheckQubits(QArray.Add(ctrls, targets)); + + MCExp(Simulator.Id, (uint)targets.Length, paulis, angle * 2.0, (uint)ctrls.Length, ctrls.GetIds(), targets.GetIds()); + } + + return QVoid.Instance; + }; + + public override Func<(IQArray, (double, Qubit, Qubit)), QVoid> ControlledAdjointBody => (args) => + { + var (ctrls, (angle, qubit1, qubit2)) = args; + + return this.ControlledBody.Invoke((ctrls, (-angle, qubit1, qubit2))); + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumSimulator/RFrac.cs b/src/Simulation/Simulators/QuantumSimulator/RFrac.cs deleted file mode 100644 index 0d84cea50bf..00000000000 --- a/src/Simulation/Simulators/QuantumSimulator/RFrac.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; - -using Microsoft.Quantum.Simulation.Core; - -namespace Microsoft.Quantum.Simulation.Simulators -{ - - public partial class QuantumSimulator - { - public class QSimRFrac : Intrinsic.RFrac - { - public QSimRFrac(QuantumSimulator m) : base(m) - { - } - - public static double Angle(long numerator, long power) => - (-2.0 * System.Math.PI * numerator) / (1 << (int)power); - - public override Func<(Pauli, long, long, Qubit), QVoid> Body => (args) => - { - var (pauli, numerator, power, qubit) = args; - var angle = Angle(numerator, power); - return R.Apply((pauli, angle, qubit)); - }; - - public override Func<(Pauli, long, long, Qubit), QVoid> AdjointBody => (args) => - { - var (pauli, numerator, power, qubit) = args; - var angle = Angle(numerator, power); - return R.Adjoint.Apply((pauli, angle, qubit)); - }; - - public override Func<(IQArray, (Pauli, long, long, Qubit)), QVoid> ControlledBody => (args) => - { - var (ctrls, (pauli, numerator, power, qubit)) = args; - var angle = Angle(numerator, power); - return R.Controlled.Apply((ctrls, (pauli, angle, qubit))); - }; - - public override Func<(IQArray, (Pauli, long, long, Qubit)), QVoid> ControlledAdjointBody => (args) => - { - var (ctrls, (pauli, numerator, power, qubit)) = args; - var angle = Angle(numerator, power); - return R.Adjoint.Controlled.Apply((ctrls, (pauli, angle, qubit))); - }; - } - } -} diff --git a/src/Simulation/Simulators/QuantumSimulator/Rx.cs b/src/Simulation/Simulators/QuantumSimulator/Rx.cs new file mode 100644 index 00000000000..4d6c60ecc84 --- /dev/null +++ b/src/Simulation/Simulators/QuantumSimulator/Rx.cs @@ -0,0 +1,61 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.Simulators +{ + + public partial class QuantumSimulator + { + public class QSimRx : Intrinsic.Rx + { + [DllImport(QSIM_DLL_NAME, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, EntryPoint = "R")] + private static extern void R(uint id, Pauli basis, double angle, uint qubit); + + [DllImport(QSIM_DLL_NAME, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, EntryPoint = "MCR")] + private static extern void MCR(uint id, Pauli basis, double angle, uint count, uint[] ctrls, uint qubit); + + private QuantumSimulator Simulator { get; } + + public QSimRx(QuantumSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func<(double, Qubit), QVoid> Body => (args) => + { + var (angle, target) = args; + Simulator.CheckQubit(target, nameof(target)); + CheckAngle(angle); + R(Simulator.Id, Pauli.PauliX, angle, (uint)target.Id); + return QVoid.Instance; + }; + + public override Func<(double, Qubit), QVoid> AdjointBody => (_args) => + { + var (angle, q1) = _args; + + return this.Body.Invoke((-angle, q1)); + }; + + public override Func<(IQArray, (double, Qubit)), QVoid> ControlledBody => (args) => + { + var (ctrls, (angle, target)) = args; + Simulator.CheckQubits(ctrls, target); + CheckAngle(angle); + MCR(Simulator.Id, Pauli.PauliX, angle, (uint)ctrls.Length, ctrls.GetIds(), (uint)target.Id); + return QVoid.Instance; + }; + + public override Func<(IQArray, (double, Qubit)), QVoid> ControlledAdjointBody => (_args) => + { + var (ctrls, (angle, q1)) = _args; + + return this.ControlledBody.Invoke((ctrls, (-angle, q1))); + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumSimulator/Ry.cs b/src/Simulation/Simulators/QuantumSimulator/Ry.cs new file mode 100644 index 00000000000..f669deaafa2 --- /dev/null +++ b/src/Simulation/Simulators/QuantumSimulator/Ry.cs @@ -0,0 +1,61 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.Simulators +{ + + public partial class QuantumSimulator + { + public class QSimRy : Intrinsic.Ry + { + [DllImport(QSIM_DLL_NAME, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, EntryPoint = "R")] + private static extern void R(uint id, Pauli basis, double angle, uint qubit); + + [DllImport(QSIM_DLL_NAME, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, EntryPoint = "MCR")] + private static extern void MCR(uint id, Pauli basis, double angle, uint count, uint[] ctrls, uint qubit); + + private QuantumSimulator Simulator { get; } + + public QSimRy(QuantumSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func<(double, Qubit), QVoid> Body => (args) => + { + var (angle, target) = args; + Simulator.CheckQubit(target, nameof(target)); + CheckAngle(angle); + R(Simulator.Id, Pauli.PauliY, angle, (uint)target.Id); + return QVoid.Instance; + }; + + public override Func<(double, Qubit), QVoid> AdjointBody => (_args) => + { + var (angle, q1) = _args; + + return this.Body.Invoke((-angle, q1)); + }; + + public override Func<(IQArray, (double, Qubit)), QVoid> ControlledBody => (args) => + { + var (ctrls, (angle, target)) = args; + Simulator.CheckQubits(ctrls, target); + CheckAngle(angle); + MCR(Simulator.Id, Pauli.PauliY, angle, (uint)ctrls.Length, ctrls.GetIds(), (uint)target.Id); + return QVoid.Instance; + }; + + public override Func<(IQArray, (double, Qubit)), QVoid> ControlledAdjointBody => (_args) => + { + var (ctrls, (angle, q1)) = _args; + + return this.ControlledBody.Invoke((ctrls, (-angle, q1))); + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumSimulator/Rz.cs b/src/Simulation/Simulators/QuantumSimulator/Rz.cs new file mode 100644 index 00000000000..db91d1be5e7 --- /dev/null +++ b/src/Simulation/Simulators/QuantumSimulator/Rz.cs @@ -0,0 +1,61 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.Simulators +{ + + public partial class QuantumSimulator + { + public class QSimRz : Intrinsic.Rz + { + [DllImport(QSIM_DLL_NAME, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, EntryPoint = "R")] + private static extern void R(uint id, Pauli basis, double angle, uint qubit); + + [DllImport(QSIM_DLL_NAME, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, EntryPoint = "MCR")] + private static extern void MCR(uint id, Pauli basis, double angle, uint count, uint[] ctrls, uint qubit); + + private QuantumSimulator Simulator { get; } + + public QSimRz(QuantumSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func<(double, Qubit), QVoid> Body => (args) => + { + var (angle, target) = args; + Simulator.CheckQubit(target, nameof(target)); + CheckAngle(angle); + R(Simulator.Id, Pauli.PauliZ, angle, (uint)target.Id); + return QVoid.Instance; + }; + + public override Func<(double, Qubit), QVoid> AdjointBody => (_args) => + { + var (angle, q1) = _args; + + return this.Body.Invoke((-angle, q1)); + }; + + public override Func<(IQArray, (double, Qubit)), QVoid> ControlledBody => (args) => + { + var (ctrls, (angle, target)) = args; + Simulator.CheckQubits(ctrls, target); + CheckAngle(angle); + MCR(Simulator.Id, Pauli.PauliZ, angle, (uint)ctrls.Length, ctrls.GetIds(), (uint)target.Id); + return QVoid.Instance; + }; + + public override Func<(IQArray, (double, Qubit)), QVoid> ControlledAdjointBody => (_args) => + { + var (ctrls, (angle, q1)) = _args; + + return this.ControlledBody.Invoke((ctrls, (-angle, q1))); + }; + } + } +} diff --git a/src/Simulation/Simulators/QuantumSimulator/SWAP.cs b/src/Simulation/Simulators/QuantumSimulator/SWAP.cs new file mode 100644 index 00000000000..201fd564a31 --- /dev/null +++ b/src/Simulation/Simulators/QuantumSimulator/SWAP.cs @@ -0,0 +1,60 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Runtime.InteropServices; +using Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Simulation.Simulators +{ + + public partial class QuantumSimulator + { + public class QSimSWAP : Intrinsic.SWAP + { + [DllImport(QSIM_DLL_NAME, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, EntryPoint = "MCX")] + private static extern void MCX(uint id, uint count, uint[] ctrls, uint qubit); + + private QuantumSimulator Simulator { get; } + + public QSimSWAP(QuantumSimulator m) : base(m) + { + this.Simulator = m; + } + + public override Func<(Qubit, Qubit), QVoid> Body => (args) => + { + var (qubit1, qubit2) = args; + var ctrls = new QArray(qubit1); + Simulator.CheckQubits(ctrls, qubit2); + + MCX(Simulator.Id, (uint)ctrls.Length, ctrls.GetIds(), (uint)qubit2.Id); + + return QVoid.Instance; + }; + + public override Func<(IQArray, (Qubit, Qubit)), QVoid> ControlledBody => (args) => + { + var (ctrls, (qubit1, qubit2)) = args; + + if ((ctrls == null) || (ctrls.Count == 0)) + { + this.Apply((qubit1, qubit2)); + } + else + { + var ctrls_1 = QArray.Add(ctrls, new QArray(qubit1)); + var ctrls_2 = QArray.Add(ctrls, new QArray(qubit2)); + Simulator.CheckQubits(ctrls_1, qubit2); + + MCX(Simulator.Id, (uint)ctrls_1.Length, ctrls_1.GetIds(), (uint)qubit2.Id); + MCX(Simulator.Id, (uint)ctrls_2.Length, ctrls_2.GetIds(), (uint)qubit1.Id); + MCX(Simulator.Id, (uint)ctrls_1.Length, ctrls_1.GetIds(), (uint)qubit2.Id); + } + + return QVoid.Instance; + }; + + } + } +} diff --git a/src/Simulation/Common/SimulatorBase.cs b/src/Simulation/Simulators/QuantumSimulator/SimulatorBase.cs similarity index 100% rename from src/Simulation/Common/SimulatorBase.cs rename to src/Simulation/Simulators/QuantumSimulator/SimulatorBase.cs diff --git a/src/Simulation/Common/StackTrace.cs b/src/Simulation/Simulators/QuantumSimulator/StackTrace.cs similarity index 100% rename from src/Simulation/Common/StackTrace.cs rename to src/Simulation/Simulators/QuantumSimulator/StackTrace.cs diff --git a/src/Simulation/TargetDefinitions/Decompositions/CCNOT.qs b/src/Simulation/TargetDefinitions/Decompositions/CCNOT.qs index 430ab0e4c9f..99772e845a0 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/CCNOT.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/CCNOT.qs @@ -2,6 +2,8 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + /// # Summary /// Applies the doubly controlled–NOT (CCNOT) gate to three qubits. /// @@ -18,6 +20,7 @@ namespace Microsoft.Quantum.Intrinsic { /// ```qsharp /// Controlled X([control1, control2], target); /// ``` + @EnableTestingViaName("Test.TargetDefinitions.CCNOT") operation CCNOT (control1 : Qubit, control2 : Qubit, target : Qubit) : Unit is Adj + Ctl { body (...) { Controlled X([control1, control2], target); diff --git a/src/Simulation/TargetDefinitions/Decompositions/CNOT.qs b/src/Simulation/TargetDefinitions/Decompositions/CNOT.qs index f6403a74e5f..7817f4fd480 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/CNOT.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/CNOT.qs @@ -2,6 +2,8 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + /// # Summary /// Applies the controlled-NOT (CNOT) gate to a pair of qubits. /// @@ -29,6 +31,7 @@ namespace Microsoft.Quantum.Intrinsic { /// ```qsharp /// Controlled X([control], target); /// ``` + @EnableTestingViaName("Test.TargetDefinitions.CNOT") operation CNOT (control : Qubit, target : Qubit) : Unit is Adj + Ctl { body (...) { Controlled X([control], target); diff --git a/src/Simulation/TargetDefinitions/Decompositions/ExpFrac.qs b/src/Simulation/TargetDefinitions/Decompositions/ExpFrac.qs index e18d4e98e0d..e6f6c55a406 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/ExpFrac.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/ExpFrac.qs @@ -4,6 +4,7 @@ namespace Microsoft.Quantum.Intrinsic { open Microsoft.Quantum.Math; open Microsoft.Quantum.Convert; + open Microsoft.Quantum.Diagnostics; /// # Summary /// Applies the exponential of a multi-qubit Pauli operator @@ -28,6 +29,7 @@ namespace Microsoft.Quantum.Intrinsic { /// the qubit register is to be rotated. /// ## qubits /// Register to apply the given rotation to. + @EnableTestingViaName("Test.TargetDefinitions.ExpFrac") operation ExpFrac (paulis : Pauli[], numerator : Int, power : Int, qubits : Qubit[]) : Unit is Adj + Ctl { let angle = (PI() * IntAsDouble(numerator)) / IntAsDouble(2 ^ power); Exp(paulis, angle, qubits); diff --git a/src/Simulation/TargetDefinitions/Decompositions/ExpFracFromIsing.qs b/src/Simulation/TargetDefinitions/Decompositions/ExpFracFromIsing.qs new file mode 100644 index 00000000000..229edf4c658 --- /dev/null +++ b/src/Simulation/TargetDefinitions/Decompositions/ExpFracFromIsing.qs @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Math; + open Microsoft.Quantum.Convert; + open Microsoft.Quantum.Diagnostics; + + /// # Summary + /// Applies the exponential of a multi-qubit Pauli operator + /// with an argument given by a dyadic fraction. + /// + /// # Description + /// \begin{align} + /// e^{i \pi k [P_0 \otimes P_1 \cdots P_{N-1}] / 2^n}, + /// \end{align} + /// where $P_i$ is the $i$th element of `paulis`, and where + /// $N = $`Length(paulis)`. + /// + /// # Input + /// ## paulis + /// Array of single-qubit Pauli values indicating the tensor product + /// factors on each qubit. + /// ## numerator + /// Numerator ($k$) in the dyadic fraction representation of the angle + /// by which the qubit register is to be rotated. + /// ## power + /// Power of two ($n$) specifying the denominator of the angle by which + /// the qubit register is to be rotated. + /// ## qubits + /// Register to apply the given rotation to. + @EnableTestingViaName("Test.TargetDefinitions.ExpFrac") + operation ExpFrac (paulis : Pauli[], numerator : Int, power : Int, qubits : Qubit[]) : Unit is Adj + Ctl { + body(...) { + CheckQubitUniqueness(qubits); + if (Length(paulis) != Length(qubits)) { fail "Arrays 'pauli' and 'target' must have the same length"; } + + if (Length(paulis) != 0) { + let indices = IndicesOfNonIdentity(paulis); + let newPaulis = Subarray(indices, paulis); + let newQubits = Subarray(indices, qubits); + + if (Length(indices) != 0) { + let (kModPositive, n) = ReducedDyadicFractionPeriodic(numerator, power); // k is odd, in the range [1,2*2^n-1] or (k,n) are both 0 + let numeratorD = PI() * IntAsDouble(kModPositive); + let theta = numeratorD * PowD(2.0, IntAsDouble(-n)); + ExpNoIdUtil(newPaulis, theta, newQubits, RFrac(_, numerator, power, _)); + } + else { + ApplyGlobalPhaseFracWithR1Frac(numerator, power); + } + } + } + adjoint(...) { + ExpFrac(paulis, -numerator, power, qubits); + } + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Decompositions/ExpFromIsing.qs b/src/Simulation/TargetDefinitions/Decompositions/ExpFromIsing.qs new file mode 100644 index 00000000000..5a9fee5ab2e --- /dev/null +++ b/src/Simulation/TargetDefinitions/Decompositions/ExpFromIsing.qs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + + /// # Summary + /// Applies the exponential of a multi-qubit Pauli operator. + /// + /// # Description + /// \begin{align} + /// e^{i \theta [P_0 \otimes P_1 \cdots P_{N-1}]}, + /// \end{align} + /// where $P_i$ is the $i$th element of `paulis`, and where + /// $N = $`Length(paulis)`. + /// + /// # Input + /// ## paulis + /// Array of single-qubit Pauli values indicating the tensor product + /// factors on each qubit. + /// ## theta + /// Angle about the given multi-qubit Pauli operator by which the + /// target register is to be rotated. + /// ## qubits + /// Register to apply the given rotation to. + @EnableTestingViaName("Test.TargetDefinitions.Exp") + operation Exp (paulis : Pauli[], theta : Double, qubits : Qubit[]) : Unit is Adj + Ctl { + body(...) { + CheckQubitUniqueness(qubits); + RotationAngleValidation(theta); + if (Length(paulis) != Length(qubits)) { fail "Arrays 'pauli' and 'qubits' must have the same length"; } + let (newPaulis, newQubits) = RemovePauliI(paulis, qubits); + + if (Length(newPaulis) != 0) { + ExpNoIdUtil(newPaulis, theta , newQubits, R(_, -2.0 * theta, _)); + } + else { + ApplyGlobalPhase(theta); + } + } + adjoint(...) { + Exp(paulis, -theta, qubits); + } + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Decompositions/IsingXX.qs b/src/Simulation/TargetDefinitions/Decompositions/IsingXX.qs new file mode 100644 index 00000000000..a527a86a634 --- /dev/null +++ b/src/Simulation/TargetDefinitions/Decompositions/IsingXX.qs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + + /// # Summary + /// Applies the two qubit Ising $XX$ rotation gate. + /// + /// # Description + /// \begin{align} + /// XX(\theta) \mathrel{:=} + /// \begin{bmatrix} + /// \cos \theta & 0 & 0 & -i\sin \theta \\\\ + /// 0 & \cos \theta & -i\sin \theta & 0 \\\\ + /// 0 & -i\sin \theta & \cos \theta & 0 \\\\ + /// -i\sin \theta & 0 & 0 & \cos \theta + /// \end{bmatrix}. + /// \end{align} + /// + /// # Input + /// ## theta + /// The angle about which the qubits are rotated. + /// ## qubit0 + /// The first qubit input to the gate. + /// ## qubit1 + /// The second qubit input to the gate. + @EnableTestingViaName("Test.TargetDefinitions.IsingXX") + operation IsingXX (theta : Double, qubit0 : Qubit, qubit1 : Qubit) : Unit is Adj + Ctl { + Exp([PauliX, PauliX], theta * 2.0, [qubit0, qubit1]); + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Decompositions/IsingYY.qs b/src/Simulation/TargetDefinitions/Decompositions/IsingYY.qs new file mode 100644 index 00000000000..fe33783729a --- /dev/null +++ b/src/Simulation/TargetDefinitions/Decompositions/IsingYY.qs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + + /// # Summary + /// Applies the two qubit Ising $YY$ rotation gate. + /// + /// # Description + /// \begin{align} + /// YY(\theta) \mathrel{:=} + /// \begin{bmatrix} + /// \cos \theta & 0 & 0 & i\sin \theta \\\\ + /// 0 & \cos \theta & -i\sin \theta & 0 \\\\ + /// 0 & -i\sin \theta & \cos \theta & 0 \\\\ + /// i\sin \theta & 0 & 0 & \cos \theta + /// \end{bmatrix}. + /// \end{align} + /// + /// # Input + /// ## theta + /// The angle about which the qubits are rotated. + /// ## qubit0 + /// The first qubit input to the gate. + /// ## qubit1 + /// The second qubit input to the gate. + @EnableTestingViaName("Test.TargetDefinitions.IsingYY") + operation IsingYY (theta : Double, qubit0 : Qubit, qubit1 : Qubit) : Unit is Adj + Ctl { + Exp([PauliY, PauliY], theta * 2.0, [qubit0, qubit1]); + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Decompositions/IsingZZ.qs b/src/Simulation/TargetDefinitions/Decompositions/IsingZZ.qs new file mode 100644 index 00000000000..3534019b726 --- /dev/null +++ b/src/Simulation/TargetDefinitions/Decompositions/IsingZZ.qs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + + /// # Summary + /// Applies the two qubit Ising $ZZ$ rotation gate. + /// + /// # Description + /// \begin{align} + /// ZZ(\theta) \mathrel{:=} + /// \begin{bmatrix} + /// e^{-i \theta / 2} & 0 & 0 & 0 \\\\ + /// 0 & e^{-i \theta / 2} & 0 & 0 \\\\ + /// 0 & 0 & e^{-i \theta / 2} & 0 \\\\ + /// 0 & 0 & 0 & e^{i \theta / 2} + /// \end{bmatrix}. + /// \end{align} + /// + /// # Input + /// ## theta + /// The angle about which the qubits are rotated. + /// ## qubit0 + /// The first qubit input to the gate. + /// ## qubit1 + /// The second qubit input to the gate. + @EnableTestingViaName("Test.TargetDefinitions.IsingZZ") + operation IsingZZ (theta : Double, qubit0 : Qubit, qubit1 : Qubit) : Unit is Adj + Ctl { + Exp([PauliZ, PauliZ], theta * 2.0, [qubit0, qubit1]); + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Decompositions/M.qs b/src/Simulation/TargetDefinitions/Decompositions/M.qs index c5066f9ee6c..a8fb33939a2 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/M.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/M.qs @@ -2,6 +2,8 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + /// # Summary /// Performs a measurement of a single qubit in the /// Pauli $Z$ basis. @@ -27,6 +29,7 @@ namespace Microsoft.Quantum.Intrinsic { /// ```qsharp /// Measure([PauliZ], [qubit]); /// ``` + @EnableTestingViaName("Test.TargetDefinitions.M") operation M (qubit : Qubit) : Result { return Measure([PauliZ], [qubit]); } diff --git a/src/Simulation/TargetDefinitions/Decompositions/MResetX.qs b/src/Simulation/TargetDefinitions/Decompositions/MResetX.qs index ae845f9b788..30568c5f002 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/MResetX.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/MResetX.qs @@ -3,6 +3,7 @@ namespace Microsoft.Quantum.Measurement { open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Diagnostics; /// # Summary /// Measures a single qubit in the X basis, @@ -20,6 +21,7 @@ namespace Microsoft.Quantum.Measurement { /// /// # Output /// The result of measuring `target` in the Pauli $X$ basis. + @EnableTestingViaName("Test.TargetDefinitions.MResetX") operation MResetX (target : Qubit) : Result { let result = Measure([PauliX], [target]); diff --git a/src/Simulation/TargetDefinitions/Decompositions/MResetXWithNoReuse.qs b/src/Simulation/TargetDefinitions/Decompositions/MResetXWithNoReuse.qs new file mode 100644 index 00000000000..0db2613018d --- /dev/null +++ b/src/Simulation/TargetDefinitions/Decompositions/MResetXWithNoReuse.qs @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Measurement { + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Diagnostics; + + /// # Summary + /// Measures a single qubit in the X basis, + /// and resets it to a fixed initial state + /// following the measurement. + /// + /// # Description + /// Performs a single-qubit measurement in the $X$-basis, + /// and ensures that the qubit is returned to $\ket{0}$ + /// following the measurement. + /// + /// # Input + /// ## target + /// A single qubit to be measured. + /// + /// # Output + /// The result of measuring `target` in the Pauli $X$ basis. + @EnableTestingViaName("Test.TargetDefinitions.MResetX") + operation MResetX (target : Qubit) : Result { + // Because the qubit cannot be reused after measurement, no actual + // reset is required. + return Measure([PauliX], [target]); + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Decompositions/MResetY.qs b/src/Simulation/TargetDefinitions/Decompositions/MResetY.qs index 41271901ab9..070a5db0d7f 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/MResetY.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/MResetY.qs @@ -3,11 +3,7 @@ namespace Microsoft.Quantum.Measurement { open Microsoft.Quantum.Intrinsic; - - internal operation BasisChangeZtoY(target : Qubit) : Unit is Adj + Ctl { - H(target); - S(target); - } + open Microsoft.Quantum.Diagnostics; /// # Summary /// Measures a single qubit in the Y basis, @@ -25,11 +21,13 @@ namespace Microsoft.Quantum.Measurement { /// /// # Output /// The result of measuring `target` in the Pauli $Y$ basis. + @EnableTestingViaName("Test.TargetDefinitions.MResetY") operation MResetY (target : Qubit) : Result { let result = Measure([PauliY], [target]); // We must return the qubit to the Z basis as well. - Adjoint BasisChangeZtoY(target); + S(target); + H(target); if (result == One) { // Recall that the +1 eigenspace of a measurement operator corresponds to diff --git a/src/Simulation/TargetDefinitions/Decompositions/MResetYWithNoReuse.qs b/src/Simulation/TargetDefinitions/Decompositions/MResetYWithNoReuse.qs new file mode 100644 index 00000000000..a2337edb403 --- /dev/null +++ b/src/Simulation/TargetDefinitions/Decompositions/MResetYWithNoReuse.qs @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Measurement { + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Diagnostics; + + /// # Summary + /// Measures a single qubit in the Y basis, + /// and resets it to a fixed initial state + /// following the measurement. + /// + /// # Description + /// Performs a single-qubit measurement in the $Y$-basis, + /// and ensures that the qubit is returned to $\ket{0}$ + /// following the measurement. + /// + /// # Input + /// ## target + /// A single qubit to be measured. + /// + /// # Output + /// The result of measuring `target` in the Pauli $Y$ basis. + @EnableTestingViaName("Test.TargetDefinitions.MResetY") + operation MResetY (target : Qubit) : Result { + // Because the qubit cannot be reused after measurement, no actual + // reset is required. + return Measure([PauliY], [target]); + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Decompositions/MResetZ.qs b/src/Simulation/TargetDefinitions/Decompositions/MResetZ.qs index 64c04237af6..3d583df4075 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/MResetZ.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/MResetZ.qs @@ -3,6 +3,7 @@ namespace Microsoft.Quantum.Measurement { open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Diagnostics; /// # Summary /// Measures a single qubit in the Z basis, @@ -20,6 +21,7 @@ namespace Microsoft.Quantum.Measurement { /// /// # Output /// The result of measuring `target` in the Pauli $Z$ basis. + @EnableTestingViaName("Test.TargetDefinitions.MResetZ") operation MResetZ (target : Qubit) : Result { let result = M(target); diff --git a/src/Simulation/TargetDefinitions/Decompositions/MResetZWithNoReuse.qs b/src/Simulation/TargetDefinitions/Decompositions/MResetZWithNoReuse.qs new file mode 100644 index 00000000000..a18daeb426b --- /dev/null +++ b/src/Simulation/TargetDefinitions/Decompositions/MResetZWithNoReuse.qs @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Measurement { + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Diagnostics; + + /// # Summary + /// Measures a single qubit in the Z basis, + /// and resets it to a fixed initial state + /// following the measurement. + /// + /// # Description + /// Performs a single-qubit measurement in the $Z$-basis, + /// and ensures that the qubit is returned to $\ket{0}$ + /// following the measurement. + /// + /// # Input + /// ## target + /// A single qubit to be measured. + /// + /// # Output + /// The result of measuring `target` in the Pauli $Z$ basis. + @EnableTestingViaName("Test.TargetDefinitions.MResetZ") + operation MResetZ (target : Qubit) : Result { + // Because the qubit cannot be reused after measurement, no actual + // reset is required. + return M(target); + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Decompositions/MeasureWithNoReuse.qs b/src/Simulation/TargetDefinitions/Decompositions/MeasureWithNoReuse.qs new file mode 100644 index 00000000000..74dac7de9e4 --- /dev/null +++ b/src/Simulation/TargetDefinitions/Decompositions/MeasureWithNoReuse.qs @@ -0,0 +1,68 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + + /// # Summary + /// Performs a joint measurement of one or more qubits in the + /// specified Pauli bases. + /// + /// # Description + /// The output result is given by the distribution: + /// \begin{align} + /// \Pr(\texttt{Zero} | \ket{\psi}) = + /// \frac12 \braket{ + /// \psi \mid| + /// \left( + /// \boldone + P_0 \otimes P_1 \otimes \cdots \otimes P_{N-1} + /// \right) \mid| + /// \psi + /// }, + /// \end{align} + /// where $P_i$ is the $i$th element of `bases`, and where + /// $N = \texttt{Length}(\texttt{bases})$. + /// That is, measurement returns a `Result` $d$ such that the eigenvalue of the + /// observed measurement effect is $(-1)^d$. + /// + /// # Input + /// ## bases + /// Array of single-qubit Pauli values indicating the tensor product + /// factors on each qubit. + /// ## qubits + /// Register of qubits to be measured. + /// + /// # Output + /// `Zero` if the $+1$ eigenvalue is observed, and `One` if + /// the $-1$ eigenvalue is observed. + /// + /// # Remarks + /// If the basis array and qubit array are different lengths, then the + /// operation will fail. + @EnableTestingViaName("Test.TargetDefinitions.Measure") + operation Measure (bases : Pauli[], qubits : Qubit[]) : Result { + CheckQubitUniqueness(qubits); + if (Length(bases) != Length(qubits)) { fail "Arrays 'bases' and 'qubits' must be of the same length."; } + if (Length(bases) == 1) { + // Because the qubit cannot be reused after measurement, there is no + // need to unprepare the Pauli mapping. + MapPauli(qubits[0], PauliZ, bases[0]); + return M(qubits[0]); + } + else { + using (q = Qubit()) { + within { + H(q); + } + apply { + for (k in 0 .. Length(bases) - 1) { + if (bases[k] == PauliX) { Controlled X([qubits[k]], q); } + if (bases[k] == PauliZ) { Controlled Z([qubits[k]], q); } + if (bases[k] == PauliY) { Controlled Y([qubits[k]], q); } + } + } + return M(q); + } + } + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Decompositions/R.qs b/src/Simulation/TargetDefinitions/Decompositions/R.qs new file mode 100644 index 00000000000..c50c71daaa4 --- /dev/null +++ b/src/Simulation/TargetDefinitions/Decompositions/R.qs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + + /// # Summary + /// Applies a rotation about the given Pauli axis. + /// + /// # Description + /// \begin{align} + /// R_{\mu}(\theta) \mathrel{:=} + /// e^{-i \theta \sigma_{\mu} / 2}, + /// \end{align} + /// where $\mu \in \{I, X, Y, Z\}$. + /// + /// # Input + /// ## pauli + /// Pauli operator ($\mu$) to be exponentiated to form the rotation. + /// ## theta + /// Angle about which the qubit is to be rotated. + /// ## qubit + /// Qubit to which the gate should be applied. + /// + /// # Remarks + /// When called with `pauli = PauliI`, this operation applies + /// a *global phase*. This phase can be significant + /// when used with the `Controlled` functor. + @EnableTestingViaName("Test.TargetDefinitions.R") + operation R (pauli : Pauli, theta : Double, qubit : Qubit) : Unit is Adj + Ctl { + if (pauli == PauliX) { + Rx(theta, qubit); + } + elif (pauli == PauliY) { + Ry(theta, qubit); + } + elif (pauli == PauliZ) { + Rz(theta, qubit); + } + else { // PauliI + RotationAngleValidation(theta); + ApplyGlobalPhase( - theta / 2.0 ); + } + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Decompositions/R1.qs b/src/Simulation/TargetDefinitions/Decompositions/R1.qs index 06678d7f707..02ed51439bd 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/R1.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/R1.qs @@ -2,6 +2,8 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + /// # Summary /// Applies a rotation about the $\ket{1}$ state by a given angle. /// @@ -23,6 +25,7 @@ namespace Microsoft.Quantum.Intrinsic { /// R(PauliZ, theta, qubit); /// R(PauliI, -theta, qubit); /// ``` + @EnableTestingViaName("Test.TargetDefinitions.R1") operation R1 (theta : Double, qubit : Qubit) : Unit is Adj + Ctl { R(PauliZ, theta, qubit); R(PauliI, -theta, qubit); diff --git a/src/Simulation/TargetDefinitions/Decompositions/R1Frac.qs b/src/Simulation/TargetDefinitions/Decompositions/R1Frac.qs index 338f32c8ff1..056e0ba9e54 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/R1Frac.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/R1Frac.qs @@ -2,6 +2,8 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + /// # Summary /// Applies a rotation about the $\ket{1}$ state by an angle specified /// as a dyadic fraction. @@ -33,6 +35,7 @@ namespace Microsoft.Quantum.Intrinsic { /// RFrac(PauliZ, -numerator, denominator + 1, qubit); /// RFrac(PauliI, numerator, denominator + 1, qubit); /// ``` + @EnableTestingViaName("Test.TargetDefinitions.R1Frac") operation R1Frac (numerator : Int, power : Int, qubit : Qubit) : Unit is Adj + Ctl { RFrac(PauliZ, -numerator, power + 1, qubit); RFrac(PauliI, numerator, power + 1, qubit); diff --git a/src/Simulation/TargetDefinitions/Decompositions/RFrac.qs b/src/Simulation/TargetDefinitions/Decompositions/RFrac.qs index a0f632c7e03..f3fdfa62b19 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/RFrac.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/RFrac.qs @@ -4,6 +4,7 @@ namespace Microsoft.Quantum.Intrinsic { open Microsoft.Quantum.Math; open Microsoft.Quantum.Convert; + open Microsoft.Quantum.Diagnostics; /// # Summary /// Applies a rotation about the given Pauli axis by an angle specified @@ -38,6 +39,7 @@ namespace Microsoft.Quantum.Intrinsic { /// // PI() is a Q# function that returns an approximation of π. /// R(pauli, -PI() * IntAsDouble(numerator) / IntAsDouble(2 ^ (power - 1)), qubit); /// ``` + @EnableTestingViaName("Test.TargetDefinitions.RFrac") operation RFrac (pauli : Pauli, numerator : Int, power : Int, qubit : Qubit) : Unit is Adj + Ctl { let angle = ((-2.0 * PI()) * IntAsDouble(numerator)) / IntAsDouble(2 ^ power); R(pauli, angle, qubit); diff --git a/src/Simulation/TargetDefinitions/Decompositions/Reset.qs b/src/Simulation/TargetDefinitions/Decompositions/Reset.qs index a5bb975894d..84b8d8ca38c 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/Reset.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/Reset.qs @@ -2,6 +2,8 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + /// # Summary /// Given a single qubit, measures it and ensures it is in the |0⟩ state /// such that it can be safely released. @@ -9,6 +11,7 @@ namespace Microsoft.Quantum.Intrinsic { /// # Input /// ## qubit /// The qubit whose state is to be reset to $\ket{0}$. + @EnableTestingViaName("Test.TargetDefinitions.Reset") operation Reset (target : Qubit) : Unit { if (M(target) == One) { X(target); diff --git a/src/Simulation/TargetDefinitions/Decompositions/ResetAll.qs b/src/Simulation/TargetDefinitions/Decompositions/ResetAll.qs index cd76adc599e..6a520c85bb7 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/ResetAll.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/ResetAll.qs @@ -2,6 +2,8 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + /// # Summary /// Given an array of qubits, measure them and ensure they are in the |0⟩ state /// such that they can be safely released. @@ -9,6 +11,7 @@ namespace Microsoft.Quantum.Intrinsic { /// # Input /// ## qubits /// An array of qubits whose states are to be reset to $\ket{0}$. + @EnableTestingViaName("Test.TargetDefinitions.ResetAll") operation ResetAll (qubits : Qubit[]) : Unit { for (qubit in qubits) { Reset(qubit); diff --git a/src/Simulation/TargetDefinitions/Decompositions/ResetWithoutReuse.qs b/src/Simulation/TargetDefinitions/Decompositions/ResetWithoutReuse.qs new file mode 100644 index 00000000000..bf7d0512f54 --- /dev/null +++ b/src/Simulation/TargetDefinitions/Decompositions/ResetWithoutReuse.qs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + + /// # Summary + /// Given a single qubit, measures it and ensures it is in the |0⟩ state + /// such that it can be safely released. + /// + /// # Input + /// ## qubit + /// The qubit whose state is to be reset to $\ket{0}$. + @EnableTestingViaName("Test.TargetDefinitions.Reset") + operation Reset (target : Qubit) : Unit { + // This platform doesn't support use of a qubit after measurement, so + // `Reset` is really just marking the qubit as measured. + let r = M(target); + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Decompositions/Rx.qs b/src/Simulation/TargetDefinitions/Decompositions/Rx.qs index d4c999a83b2..e7cf9c8be1c 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/Rx.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/Rx.qs @@ -2,6 +2,8 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + /// # Summary /// Applies a rotation about the $x$-axis by a given angle. /// @@ -26,6 +28,7 @@ namespace Microsoft.Quantum.Intrinsic { /// ```qsharp /// R(PauliX, theta, qubit); /// ``` + @EnableTestingViaName("Test.TargetDefinitions.Rx") operation Rx (theta : Double, qubit : Qubit) : Unit is Adj + Ctl { body (...) { R(PauliX, theta, qubit); diff --git a/src/Simulation/TargetDefinitions/Decompositions/Ry.qs b/src/Simulation/TargetDefinitions/Decompositions/Ry.qs index e68732523b6..ac1cb18dcfa 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/Ry.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/Ry.qs @@ -2,6 +2,8 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + /// # Summary /// Applies a rotation about the $y$-axis by a given angle. /// @@ -26,6 +28,7 @@ namespace Microsoft.Quantum.Intrinsic { /// ```qsharp /// R(PauliY, theta, qubit); /// ``` + @EnableTestingViaName("Test.TargetDefinitions.Ry") operation Ry (theta : Double, qubit : Qubit) : Unit is Adj + Ctl { body (...) { R(PauliY, theta, qubit); diff --git a/src/Simulation/TargetDefinitions/Decompositions/Rz.qs b/src/Simulation/TargetDefinitions/Decompositions/Rz.qs index 30956ac6640..08d0e2b239b 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/Rz.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/Rz.qs @@ -2,6 +2,8 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + /// # Summary /// Applies a rotation about the $z$-axis by a given angle. /// @@ -26,6 +28,7 @@ namespace Microsoft.Quantum.Intrinsic { /// ```qsharp /// R(PauliZ, theta, qubit); /// ``` + @EnableTestingViaName("Test.TargetDefinitions.Rz") operation Rz (theta : Double, qubit : Qubit) : Unit is Adj + Ctl { body (...) { R(PauliZ, theta, qubit); diff --git a/src/Simulation/TargetDefinitions/Decompositions/SWAP.qs b/src/Simulation/TargetDefinitions/Decompositions/SWAP.qs index 19cc13a1634..6952df79af6 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/SWAP.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/SWAP.qs @@ -2,6 +2,8 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + /// # Summary /// Applies the SWAP gate to a pair of qubits. /// @@ -31,6 +33,7 @@ namespace Microsoft.Quantum.Intrinsic { /// CNOT(qubit2, qubit1); /// CNOT(qubit1, qubit2); /// ``` + @EnableTestingViaName("Test.TargetDefinitions.SWAP") operation SWAP (qubit1 : Qubit, qubit2 : Qubit) : Unit is Adj + Ctl { body (...) { CNOT(qubit1, qubit2); diff --git a/src/Simulation/TargetDefinitions/Decompositions/SetToBasisState.qs b/src/Simulation/TargetDefinitions/Decompositions/SetToBasisState.qs index ff7ec846edf..740925d833c 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/SetToBasisState.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/SetToBasisState.qs @@ -3,6 +3,7 @@ namespace Microsoft.Quantum.Measurement { open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Diagnostics; /// # Summary /// Sets a qubit to a given computational basis state by measuring the @@ -17,6 +18,7 @@ namespace Microsoft.Quantum.Measurement { /// # Remarks /// As an invariant of this operation, calling `M(q)` immediately /// after `SetToBasisState(result, q)` will return `result`. + @EnableTestingViaName("Test.TargetDefinitions.SetToBasisState") operation SetToBasisState(desired : Result, target : Qubit) : Unit { if (desired != M(target)) { X(target); diff --git a/src/Simulation/TargetDefinitions/Decompositions/Utils.qs b/src/Simulation/TargetDefinitions/Decompositions/Utils.qs new file mode 100644 index 00000000000..f0c38c1bfc0 --- /dev/null +++ b/src/Simulation/TargetDefinitions/Decompositions/Utils.qs @@ -0,0 +1,173 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + + @EnableTestingViaName("Test.TargetDefinitions.ExpNoIdUtil") + internal operation ExpNoIdUtil (paulis : Pauli[], theta : Double, qubits : Qubit[], rotation : ((Pauli, Qubit) => Unit is Adj + Ctl)) : Unit is Ctl { + if (Length(paulis) != Length(qubits)) { fail "Arrays 'paulis' and 'qubits' must have the same length"; } + if (Length(paulis) == 1) { + rotation(paulis[0], qubits[0]); + } + elif (Length(paulis) == 2) { + within { + MapPauli(qubits[1], paulis[0], paulis[1]); + } + apply { + if (paulis[0] == PauliX) { + IsingXX(theta / 2.0, qubits[0], qubits[1]); + } elif (paulis[0] == PauliY) { + IsingYY(theta / 2.0, qubits[0], qubits[1]); + } elif (paulis[0] == PauliZ) { + IsingZZ(theta / 2.0, qubits[0], qubits[1]); + } else { + fail "Type2 decompositions do not support PauliI as an input to Exp"; + } + } + } + else { // Length(paulis) > 2 + within { + for (i in 0 .. Length(paulis) - 1) { + MapPauli(qubits[i], PauliZ, paulis[i]); + } + SpreadZ(qubits[1], qubits[2 .. Length(qubits) - 1]); + } + apply { + IsingZZ(theta / 2.0, qubits[0], qubits[1]); + } + } + } + + @EnableTestingViaName("Test.TargetDefinitions.SpreadZ") + internal operation SpreadZ (from : Qubit, to : Qubit[]) : Unit is Adj { + if (Length(to) > 0) { + CNOT(to[0], from); + if (Length(to) > 1) { + let half = Length(to) / 2; + SpreadZ(to[0], to[half + 1 .. Length(to) - 1]); + SpreadZ(from, to[1 .. half]); + } + } + } + + @EnableTestingViaName("Test.TargetDefinitions.ApplyGlobalPhase") + internal operation ApplyGlobalPhase (theta : Double) : Unit is Ctl + Adj { + body(...) {} + controlled(controls, (...)) { + if (Length(controls) > 0) { + let qubit = controls[0]; + let rest = controls[1...]; + // Invoke Controlled R1, which will recursively call back into ApplyGlobalPhase. + // Each time the controls is one shorter, until it is empty and the recursion stops. + Controlled R1(rest, (theta, qubit)); + } + } + } + + @EnableTestingViaName("Test.TargetDefinitions.ApplyGlobalPhaseFracWithR1Frac") + internal operation ApplyGlobalPhaseFracWithR1Frac (numerator : Int, power : Int) : Unit is Adj + Ctl { + body(...) {} + controlled(ctrls, ... ) { + let numControls = Length(ctrls); + if (numControls > 0 ) { + // Invoke Controlled R1Frac, which will recursively call back into ApplyGlobalPhase. + // Each time the controls is one shorter, until it is empty and the recursion stops. + Controlled R1Frac(ctrls[1 .. numControls - 1], (numerator, power, ctrls[0])); + } + } + } + + @EnableTestingViaName("Test.TargetDefinitions.MapPauli") + internal operation MapPauli (qubit : Qubit, from : Pauli, to : Pauli) : Unit is Adj { + if (from == to) { + } + elif ((from == PauliZ and to == PauliX) or (from == PauliX and to == PauliZ)) { + H(qubit); + } + elif (from == PauliZ and to == PauliY) { + H(qubit); + S(qubit); + H(qubit); + } + elif (from == PauliY and to == PauliZ) { + H(qubit); + Adjoint S(qubit); + H(qubit); + } + elif (from == PauliY and to == PauliX) { + S(qubit); + } + elif (from == PauliX and to == PauliY) { + Adjoint S(qubit); + } + else { + fail "Unsupported input"; + } + } + + @EnableTestingViaName("Test.TargetDefinitions.ReducedDyadicFraction") + internal function ReducedDyadicFraction (numerator : Int, denominatorPowerOfTwo : Int) : (Int, Int) { + if (numerator == 0) { return (0,0); } + mutable num = numerator; + mutable denPow = denominatorPowerOfTwo; + while(num % 2 == 0) { + set num /= 2; + set denPow += 1; + } + return (num,denPow); + } + + @EnableTestingViaName("Test.TargetDefinitions.ReducedDyadicFractionPeriodic") + internal function ReducedDyadicFractionPeriodic (numerator : Int, denominatorPowerOfTwo : Int) : (Int, Int) { + let (k,n) = ReducedDyadicFraction(numerator,denominatorPowerOfTwo); // k is odd, or (k,n) are both 0 + let period = 2*2^n; // \pi k / 2^n is 2\pi periodic, therefore k is 2 * 2^n periodic + let kMod = k % period; // if k was negative, we get kMod in a range [-period + 1, 0] + let kModPositive = kMod >= 0 ? kMod | kMod + period; // kModPositive is in the range [0, period - 1] + return (kModPositive, n); + } + + // TODO(swernli): Consider removing this in favor of pulling Microsoft.Quantum.Arrays.Subarray + // into the runtime. + @EnableTestingViaName("Test.TargetDefinitions.Subarray") + internal function Subarray<'T> (indices : Int[], array : 'T[]) : 'T[] { + let nSliced = Length(indices); + mutable sliced = new 'T[nSliced]; + + for (idx in 0 .. nSliced - 1) { + set sliced w/= idx <- array[indices[idx]]; + } + + return sliced; + } + + @EnableTestingViaName("Test.TargetDefinitions.IndicesOfNonIdentity") + internal function IndicesOfNonIdentity(paulies : Pauli[]) : Int[] { + mutable nonIdPauliCount = 0; + + for (i in 0 .. Length(paulies) - 1) { + if (paulies[i] != PauliI) { set nonIdPauliCount += 1; } + } + + mutable indices = new Int[nonIdPauliCount]; + mutable index = 0; + + for (i in 0 .. Length(paulies) - 1) { + if (paulies[i] != PauliI) { + set indices w/= index <- i; + set index = index + 1; + } + } + + return indices; + } + + @EnableTestingViaName("Test.TargetDefinitions.RemovePauliI") + internal function RemovePauliI(paulis : Pauli[], qubits : Qubit[]) : (Pauli[], Qubit[]) { + let indices = IndicesOfNonIdentity(paulis); + let newPaulis = Subarray(indices, paulis); + let newQubits = Subarray(indices, qubits); + return (newPaulis, newQubits); + } + +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Intrinsic/Checks.qs b/src/Simulation/TargetDefinitions/Intrinsic/Checks.qs new file mode 100644 index 00000000000..37bcc86889b --- /dev/null +++ b/src/Simulation/TargetDefinitions/Intrinsic/Checks.qs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + + /// # Summary + /// Checks that all qubits operated on are unique. + /// + /// # Description + /// \begin{align} + /// e^{i \theta [P_0 \otimes P_1 \cdots P_{N-1}]}, + /// \end{align} + /// where $P_i$ is the $i$th element of `paulis`, and where + /// $N = $`Length(paulis)`. + /// + /// # Input + /// ## qubits + /// The array of qubits to verify for uniqueness. In the controlled variant + /// the full list of qubits among targets and controls are verified to be unique. + @EnableTestingViaName("Test.TargetDefinitions.CheckQubitUniqueness") + operation CheckQubitUniqueness (qubits : Qubit[]) : Unit is Adj + Ctl{ + body intrinsic; + adjoint self; + } + + + /// # Summary + /// Validates that the given angle is a Double that can be used for rotation. + /// + /// # Description + /// Validates that the value of theDouble representing a rotation angle is neither infinite nor NaN. + /// + /// # Input + /// ## angle + /// The Double to validate. + @EnableTestingViaName("Test.TargetDefinitions.RotationAngleValidation") + function RotationAngleValidation (angle : Double) : Unit { + body intrinsic; + } + +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Intrinsic/Exp.qs b/src/Simulation/TargetDefinitions/Intrinsic/Exp.qs index 0d008f67b25..df58c4a3f3c 100644 --- a/src/Simulation/TargetDefinitions/Intrinsic/Exp.qs +++ b/src/Simulation/TargetDefinitions/Intrinsic/Exp.qs @@ -2,6 +2,8 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + /// # Summary /// Applies the exponential of a multi-qubit Pauli operator. /// @@ -21,6 +23,7 @@ namespace Microsoft.Quantum.Intrinsic { /// target register is to be rotated. /// ## qubits /// Register to apply the given rotation to. + @EnableTestingViaName("Test.TargetDefinitions.Exp") operation Exp (paulis : Pauli[], theta : Double, qubits : Qubit[]) : Unit is Adj + Ctl { body intrinsic; } diff --git a/src/Simulation/TargetDefinitions/Intrinsic/H.qs b/src/Simulation/TargetDefinitions/Intrinsic/H.qs index 25a12838d32..740796ddd0b 100644 --- a/src/Simulation/TargetDefinitions/Intrinsic/H.qs +++ b/src/Simulation/TargetDefinitions/Intrinsic/H.qs @@ -2,6 +2,8 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + /// # Summary /// Applies the Hadamard transformation to a single qubit. /// @@ -18,6 +20,7 @@ namespace Microsoft.Quantum.Intrinsic { /// # Input /// ## qubit /// Qubit to which the gate should be applied. + @EnableTestingViaName("Test.TargetDefinitions.H") operation H (qubit : Qubit) : Unit is Adj + Ctl { body intrinsic; adjoint self; diff --git a/src/Simulation/TargetDefinitions/Intrinsic/I.qs b/src/Simulation/TargetDefinitions/Intrinsic/I.qs index 57a0a1d3125..39ddebc3797 100644 --- a/src/Simulation/TargetDefinitions/Intrinsic/I.qs +++ b/src/Simulation/TargetDefinitions/Intrinsic/I.qs @@ -2,12 +2,15 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + /// # Summary /// Performs the identity operation (no-op) on a single qubit. /// /// # Remarks /// This is a no-op. It is provided for completeness and because /// sometimes it is useful to call the identity in an algorithm or to pass it as a parameter. + @EnableTestingViaName("Test.TargetDefinitions.I") operation I (target : Qubit) : Unit is Adj + Ctl { body (...) { } adjoint self; diff --git a/src/Simulation/TargetDefinitions/Intrinsic/IsingXX.qs b/src/Simulation/TargetDefinitions/Intrinsic/IsingXX.qs new file mode 100644 index 00000000000..51a88e4ac9a --- /dev/null +++ b/src/Simulation/TargetDefinitions/Intrinsic/IsingXX.qs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + + /// # Summary + /// Applies the two qubit Ising $XX$ rotation gate. + /// + /// # Description + /// \begin{align} + /// XX(\theta) \mathrel{:=} + /// \begin{bmatrix} + /// \cos \theta & 0 & 0 & -i\sin \theta \\\\ + /// 0 & \cos \theta & -i\sin \theta & 0 \\\\ + /// 0 & -i\sin \theta & \cos \theta & 0 \\\\ + /// -i\sin \theta & 0 & 0 & \cos \theta + /// \end{bmatrix}. + /// \end{align} + /// + /// # Input + /// ## theta + /// The angle about which the qubits are rotated. + /// ## qubit0 + /// The first qubit input to the gate. + /// ## qubit1 + /// The second qubit input to the gate. + @EnableTestingViaName("Test.TargetDefinitions.IsingXX") + operation IsingXX (theta : Double, qubit0 : Qubit, qubit1 : Qubit) : Unit is Adj + Ctl { + body intrinsic; + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Intrinsic/IsingYY.qs b/src/Simulation/TargetDefinitions/Intrinsic/IsingYY.qs new file mode 100644 index 00000000000..03e1e7b7fa2 --- /dev/null +++ b/src/Simulation/TargetDefinitions/Intrinsic/IsingYY.qs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + + /// # Summary + /// Applies the two qubit Ising $YY$ rotation gate. + /// + /// # Description + /// \begin{align} + /// YY(\theta) \mathrel{:=} + /// \begin{bmatrix} + /// \cos \theta & 0 & 0 & i\sin \theta \\\\ + /// 0 & \cos \theta & -i\sin \theta & 0 \\\\ + /// 0 & -i\sin \theta & \cos \theta & 0 \\\\ + /// i\sin \theta & 0 & 0 & \cos \theta + /// \end{bmatrix}. + /// \end{align} + /// + /// # Input + /// ## theta + /// The angle about which the qubits are rotated. + /// ## qubit0 + /// The first qubit input to the gate. + /// ## qubit1 + /// The second qubit input to the gate. + @EnableTestingViaName("Test.TargetDefinitions.IsingYY") + operation IsingYY (theta : Double, qubit0 : Qubit, qubit1 : Qubit) : Unit is Adj + Ctl { + body intrinsic; + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Intrinsic/IsingZZ.qs b/src/Simulation/TargetDefinitions/Intrinsic/IsingZZ.qs new file mode 100644 index 00000000000..ae5c0f86ec7 --- /dev/null +++ b/src/Simulation/TargetDefinitions/Intrinsic/IsingZZ.qs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + + /// # Summary + /// Applies the two qubit Ising $ZZ$ rotation gate. + /// + /// # Description + /// \begin{align} + /// ZZ(\theta) \mathrel{:=} + /// \begin{bmatrix} + /// e^{-i \theta / 2} & 0 & 0 & 0 \\\\ + /// 0 & e^{-i \theta / 2} & 0 & 0 \\\\ + /// 0 & 0 & e^{-i \theta / 2} & 0 \\\\ + /// 0 & 0 & 0 & e^{i \theta / 2} + /// \end{bmatrix}. + /// \end{align} + /// + /// # Input + /// ## theta + /// The angle about which the qubits are rotated. + /// ## qubit0 + /// The first qubit input to the gate. + /// ## qubit1 + /// The second qubit input to the gate. + @EnableTestingViaName("Test.TargetDefinitions.IsingZZ") + operation IsingZZ (theta : Double, qubit0 : Qubit, qubit1 : Qubit) : Unit is Adj + Ctl { + body intrinsic; + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Intrinsic/M.qs b/src/Simulation/TargetDefinitions/Intrinsic/M.qs new file mode 100644 index 00000000000..7c44f88a5d1 --- /dev/null +++ b/src/Simulation/TargetDefinitions/Intrinsic/M.qs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + + /// # Summary + /// Performs a measurement of a single qubit in the + /// Pauli $Z$ basis. + /// + /// # Description + /// The output result is given by + /// the distribution + /// \begin{align} + /// \Pr(\texttt{Zero} | \ket{\psi}) = + /// \braket{\psi | 0} \braket{0 | \psi}. + /// \end{align} + /// + /// # Input + /// ## qubit + /// Qubit to be measured. + /// + /// # Output + /// `Zero` if the $+1$ eigenvalue is observed, and `One` if + /// the $-1$ eigenvalue is observed. + /// + /// # Remarks + /// Equivalent to: + /// ```qsharp + /// Measure([PauliZ], [qubit]); + /// ``` + @EnableTestingViaName("Test.TargetDefinitions.M") + operation M (qubit : Qubit) : Result { + body intrinsic; + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Intrinsic/Measure.qs b/src/Simulation/TargetDefinitions/Intrinsic/Measure.qs index 957726d85da..ada792ca5f4 100644 --- a/src/Simulation/TargetDefinitions/Intrinsic/Measure.qs +++ b/src/Simulation/TargetDefinitions/Intrinsic/Measure.qs @@ -2,6 +2,8 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + /// # Summary /// Performs a joint measurement of one or more qubits in the /// specified Pauli bases. @@ -37,6 +39,7 @@ namespace Microsoft.Quantum.Intrinsic { /// # Remarks /// If the basis array and qubit array are different lengths, then the /// operation will fail. + @EnableTestingViaName("Test.TargetDefinitions.Measure") operation Measure (bases : Pauli[], qubits : Qubit[]) : Result { body intrinsic; } diff --git a/src/Simulation/TargetDefinitions/Intrinsic/R.qs b/src/Simulation/TargetDefinitions/Intrinsic/R.qs index ff64e63631b..8deee174ebb 100644 --- a/src/Simulation/TargetDefinitions/Intrinsic/R.qs +++ b/src/Simulation/TargetDefinitions/Intrinsic/R.qs @@ -2,6 +2,8 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + /// # Summary /// Applies a rotation about the given Pauli axis. /// @@ -24,6 +26,7 @@ namespace Microsoft.Quantum.Intrinsic { /// When called with `pauli = PauliI`, this operation applies /// a *global phase*. This phase can be significant /// when used with the `Controlled` functor. + @EnableTestingViaName("Test.TargetDefinitions.R") operation R (pauli : Pauli, theta : Double, qubit : Qubit) : Unit is Adj + Ctl { body intrinsic; } diff --git a/src/Simulation/TargetDefinitions/Intrinsic/Rx.qs b/src/Simulation/TargetDefinitions/Intrinsic/Rx.qs new file mode 100644 index 00000000000..20aa42633b7 --- /dev/null +++ b/src/Simulation/TargetDefinitions/Intrinsic/Rx.qs @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + + /// # Summary + /// Applies a rotation about the $x$-axis by a given angle. + /// + /// # Description + /// \begin{align} + /// R_x(\theta) \mathrel{:=} + /// e^{-i \theta \sigma_x / 2} = + /// \begin{bmatrix} + /// \cos \frac{\theta}{2} & -i\sin \frac{\theta}{2} \\\\ + /// -i\sin \frac{\theta}{2} & \cos \frac{\theta}{2} + /// \end{bmatrix}. + /// \end{align} + /// + /// # Input + /// ## theta + /// Angle about which the qubit is to be rotated. + /// ## qubit + /// Qubit to which the gate should be applied. + /// + /// # Remarks + /// Equivalent to: + /// ```qsharp + /// R(PauliX, theta, qubit); + /// ``` + @EnableTestingViaName("Test.TargetDefinitions.Rx") + operation Rx (theta : Double, qubit : Qubit) : Unit is Adj + Ctl { + body intrinsic; + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Intrinsic/Ry.qs b/src/Simulation/TargetDefinitions/Intrinsic/Ry.qs new file mode 100644 index 00000000000..e8df5d1fe88 --- /dev/null +++ b/src/Simulation/TargetDefinitions/Intrinsic/Ry.qs @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + + /// # Summary + /// Applies a rotation about the $y$-axis by a given angle. + /// + /// # Description + /// \begin{align} + /// R_y(\theta) \mathrel{:=} + /// e^{-i \theta \sigma_y / 2} = + /// \begin{bmatrix} + /// \cos \frac{\theta}{2} & -\sin \frac{\theta}{2} \\\\ + /// \sin \frac{\theta}{2} & \cos \frac{\theta}{2} + /// \end{bmatrix}. + /// \end{align} + /// + /// # Input + /// ## theta + /// Angle about which the qubit is to be rotated. + /// ## qubit + /// Qubit to which the gate should be applied. + /// + /// # Remarks + /// Equivalent to: + /// ```qsharp + /// R(PauliY, theta, qubit); + /// ``` + @EnableTestingViaName("Test.TargetDefinitions.Ry") + operation Ry (theta : Double, qubit : Qubit) : Unit is Adj + Ctl { + body intrinsic; + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Intrinsic/Rz.qs b/src/Simulation/TargetDefinitions/Intrinsic/Rz.qs new file mode 100644 index 00000000000..ca7c2d4d74c --- /dev/null +++ b/src/Simulation/TargetDefinitions/Intrinsic/Rz.qs @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + + /// # Summary + /// Applies a rotation about the $z$-axis by a given angle. + /// + /// # Description + /// \begin{align} + /// R_z(\theta) \mathrel{:=} + /// e^{-i \theta \sigma_z / 2} = + /// \begin{bmatrix} + /// e^{-i \theta / 2} & 0 \\\\ + /// 0 & e^{i \theta / 2} + /// \end{bmatrix}. + /// \end{align} + /// + /// # Input + /// ## theta + /// Angle about which the qubit is to be rotated. + /// ## qubit + /// Qubit to which the gate should be applied. + /// + /// # Remarks + /// Equivalent to: + /// ```qsharp + /// R(PauliZ, theta, qubit); + /// ``` + @EnableTestingViaName("Test.TargetDefinitions.Rz") + operation Rz (theta : Double, qubit : Qubit) : Unit is Adj + Ctl { + body intrinsic; + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Intrinsic/S.qs b/src/Simulation/TargetDefinitions/Intrinsic/S.qs index e30b637d086..816c8771b31 100644 --- a/src/Simulation/TargetDefinitions/Intrinsic/S.qs +++ b/src/Simulation/TargetDefinitions/Intrinsic/S.qs @@ -2,6 +2,8 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + /// # Summary /// Applies the π/4 phase gate to a single qubit. /// @@ -17,6 +19,7 @@ namespace Microsoft.Quantum.Intrinsic { /// # Input /// ## qubit /// Qubit to which the gate should be applied. + @EnableTestingViaName("Test.TargetDefinitions.S") operation S (qubit : Qubit) : Unit is Adj + Ctl { body intrinsic; } diff --git a/src/Simulation/TargetDefinitions/Intrinsic/SWAP.qs b/src/Simulation/TargetDefinitions/Intrinsic/SWAP.qs new file mode 100644 index 00000000000..9b9c80138ed --- /dev/null +++ b/src/Simulation/TargetDefinitions/Intrinsic/SWAP.qs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + + /// # Summary + /// Applies the SWAP gate to a pair of qubits. + /// + /// # Description + /// \begin{align} + /// \operatorname{SWAP} \mathrel{:=} + /// \begin{bmatrix} + /// 1 & 0 & 0 & 0 \\\\ + /// 0 & 0 & 1 & 0 \\\\ + /// 0 & 1 & 0 & 0 \\\\ + /// 0 & 0 & 0 & 1 + /// \end{bmatrix}, + /// \end{align} + /// + /// where rows and columns are ordered as in the quantum concepts guide. + /// + /// # Input + /// ## qubit1 + /// First qubit to be swapped. + /// ## qubit2 + /// Second qubit to be swapped. + /// + /// # Remarks + /// Equivalent to: + /// ```qsharp + /// CNOT(qubit1, qubit2); + /// CNOT(qubit2, qubit1); + /// CNOT(qubit1, qubit2); + /// ``` + @EnableTestingViaName("Test.TargetDefinitions.SWAP") + operation SWAP (qubit1 : Qubit, qubit2 : Qubit) : Unit is Adj + Ctl { + body intrinsic; + adjoint self; + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Intrinsic/T.qs b/src/Simulation/TargetDefinitions/Intrinsic/T.qs index 287ec3087bc..dc3affe449a 100644 --- a/src/Simulation/TargetDefinitions/Intrinsic/T.qs +++ b/src/Simulation/TargetDefinitions/Intrinsic/T.qs @@ -2,6 +2,8 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + /// # Summary /// Applies the π/8 gate to a single qubit. /// @@ -17,6 +19,7 @@ namespace Microsoft.Quantum.Intrinsic { /// # Input /// ## qubit /// Qubit to which the gate should be applied. + @EnableTestingViaName("Test.TargetDefinitions.T") operation T (qubit : Qubit) : Unit is Adj + Ctl { body intrinsic; } diff --git a/src/Simulation/TargetDefinitions/Intrinsic/X.qs b/src/Simulation/TargetDefinitions/Intrinsic/X.qs index 522592f537a..8b5f8feb62b 100644 --- a/src/Simulation/TargetDefinitions/Intrinsic/X.qs +++ b/src/Simulation/TargetDefinitions/Intrinsic/X.qs @@ -2,6 +2,8 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + /// # Summary /// Applies the Pauli $X$ gate. /// @@ -17,6 +19,7 @@ namespace Microsoft.Quantum.Intrinsic { /// # Input /// ## qubit /// Qubit to which the gate should be applied. + @EnableTestingViaName("Test.TargetDefinitions.X") operation X (qubit : Qubit) : Unit is Adj + Ctl { body intrinsic; adjoint self; diff --git a/src/Simulation/TargetDefinitions/Intrinsic/Y.qs b/src/Simulation/TargetDefinitions/Intrinsic/Y.qs index 91769077adc..92b28478843 100644 --- a/src/Simulation/TargetDefinitions/Intrinsic/Y.qs +++ b/src/Simulation/TargetDefinitions/Intrinsic/Y.qs @@ -2,6 +2,8 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + /// # Summary /// Applies the Pauli $Y$ gate. /// @@ -17,6 +19,7 @@ namespace Microsoft.Quantum.Intrinsic { /// # Input /// ## qubit /// Qubit to which the gate should be applied. + @EnableTestingViaName("Test.TargetDefinitions.Y") operation Y (qubit : Qubit) : Unit is Adj + Ctl { body intrinsic; adjoint self; diff --git a/src/Simulation/TargetDefinitions/Intrinsic/Z.qs b/src/Simulation/TargetDefinitions/Intrinsic/Z.qs index 9d505596f15..a05f34c60c8 100644 --- a/src/Simulation/TargetDefinitions/Intrinsic/Z.qs +++ b/src/Simulation/TargetDefinitions/Intrinsic/Z.qs @@ -2,6 +2,8 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Diagnostics; + /// # Summary /// Applies the Pauli $Z$ gate. /// @@ -17,6 +19,7 @@ namespace Microsoft.Quantum.Intrinsic { /// # Input /// ## qubit /// Qubit to which the gate should be applied. + @EnableTestingViaName("Test.TargetDefinitions.Z") operation Z (qubit : Qubit) : Unit is Adj + Ctl { body intrinsic; adjoint self; diff --git a/src/Simulation/TargetDefinitions/TargetPackages/QsharpCore.Package.props b/src/Simulation/TargetDefinitions/TargetPackages/QsharpCore.Package.props index 06d5e3117ea..bf9a8f3b89c 100644 --- a/src/Simulation/TargetDefinitions/TargetPackages/QsharpCore.Package.props +++ b/src/Simulation/TargetDefinitions/TargetPackages/QsharpCore.Package.props @@ -12,6 +12,8 @@ + + @@ -20,6 +22,9 @@ + + + diff --git a/src/Simulation/TargetDefinitions/TargetPackages/Type2.Package.props b/src/Simulation/TargetDefinitions/TargetPackages/Type2.Package.props new file mode 100644 index 00000000000..be0f1d9635e --- /dev/null +++ b/src/Simulation/TargetDefinitions/TargetPackages/Type2.Package.props @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Simulation/Type2Core/Microsoft.Quantum.Type2.Core.csproj b/src/Simulation/Type2Core/Microsoft.Quantum.Type2.Core.csproj new file mode 100644 index 00000000000..ac0bc289697 --- /dev/null +++ b/src/Simulation/Type2Core/Microsoft.Quantum.Type2.Core.csproj @@ -0,0 +1,47 @@ + + + + + + + + + netstandard2.1 + true + false + false + + + + Microsoft + Type2 Targeting support for the Q# programming language. + See: https://docs.microsoft.com/en-us/quantum/relnotes/ + MIT + https://github.com/microsoft/qsharp-runtime + qdk-nuget-icon.png + Quantum Q# Qsharp + true + + + + + + + + + + + + + + + + + + + + + + + +