From 49393b9f2ad0a6618d8258cda364c7acb8bc6c88 Mon Sep 17 00:00:00 2001 From: Raphael Koh Date: Wed, 22 Jul 2020 14:14:11 -0400 Subject: [PATCH 01/14] Allow operations in arguments for `GetNonQubitArgumentsAsString` (#314) * Handle operations as arguments in GetNonQubitArgumentsAsString * Handle null values for IApplyData types --- src/Simulation/Core/TypeExtensions.cs | 8 ++++- .../Circuits/RuntimeMetadataTest.qs | 5 ++++ .../Simulators.Tests/RuntimeMetadataTests.cs | 24 ++++++++++++++- .../Simulators.Tests/TypeExtensionsTest.cs | 29 +++++++++++++++++-- 4 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/Simulation/Core/TypeExtensions.cs b/src/Simulation/Core/TypeExtensions.cs index c47650b0b77..59cb0370b52 100644 --- a/src/Simulation/Core/TypeExtensions.cs +++ b/src/Simulation/Core/TypeExtensions.cs @@ -159,10 +159,16 @@ public static Type[] GetTupleFieldTypes(this Type arg) // If object is a Qubit, QVoid, or array of Qubits, ignore it (i.e. return null) if (o is Qubit || o is QVoid || o is IEnumerable) return null; + // If object is an ICallable, return its name + if (o is ICallable op) + { + return op.Name; + } + // If object is an IApplyData, recursively extract arguments if (o is IApplyData data) { - return data.Value.GetNonQubitArgumentsAsString(); + return data.Value?.GetNonQubitArgumentsAsString(); } // If object is a string, enclose it in quotations diff --git a/src/Simulation/Simulators.Tests/Circuits/RuntimeMetadataTest.qs b/src/Simulation/Simulators.Tests/Circuits/RuntimeMetadataTest.qs index 668f7ee5bf5..b75e70fb7d5 100644 --- a/src/Simulation/Simulators.Tests/Circuits/RuntimeMetadataTest.qs +++ b/src/Simulation/Simulators.Tests/Circuits/RuntimeMetadataTest.qs @@ -11,6 +11,11 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits { operation Empty () : Unit is Ctl + Adj { } + operation WrapperOp (op: (Qubit => Unit), q : Qubit) : Unit { + op(q); + Reset(q); + } + operation HOp (q : Qubit) : Unit { H(q); Reset(q); diff --git a/src/Simulation/Simulators.Tests/RuntimeMetadataTests.cs b/src/Simulation/Simulators.Tests/RuntimeMetadataTests.cs index 629417598b0..d41b15764fa 100644 --- a/src/Simulation/Simulators.Tests/RuntimeMetadataTests.cs +++ b/src/Simulation/Simulators.Tests/RuntimeMetadataTests.cs @@ -410,10 +410,32 @@ public void EmptyOperation() Assert.Equal(op.GetRuntimeMetadata(args), expected); } + [Fact] + public void OperationAsArgument() + { + var q = new FreeQubit(0); + var opArg = new QuantumSimulator().Get(); + var op = new QuantumSimulator().Get(); + var args = op.__dataIn((opArg, q)); + var expected = new RuntimeMetadata() + { + Label = "WrapperOp", + FormattedNonQubitArgs = "(HOp)", + IsAdjoint = false, + IsControlled = false, + IsMeasurement = false, + IsComposite = false, + Children = null, + Controls = new List() { }, + Targets = new List() { q }, + }; + + Assert.Equal(op.GetRuntimeMetadata(args), expected); + } + [Fact] public void NestedOperation() { - var measureQubit = new FreeQubit(0); var op = new QuantumSimulator().Get(); var args = op.__dataIn(QVoid.Instance); var expected = new RuntimeMetadata() diff --git a/src/Simulation/Simulators.Tests/TypeExtensionsTest.cs b/src/Simulation/Simulators.Tests/TypeExtensionsTest.cs index 5fa2f260610..a7942f7f110 100644 --- a/src/Simulation/Simulators.Tests/TypeExtensionsTest.cs +++ b/src/Simulation/Simulators.Tests/TypeExtensionsTest.cs @@ -33,6 +33,16 @@ public void BasicTypes() Assert.Equal("\"\"", "".GetNonQubitArgumentsAsString()); } + [Fact] + public void OperationTypes() + { + var op = new QuantumSimulator().Get(); + Assert.Equal("H", op.GetNonQubitArgumentsAsString()); + + var op2 = new QuantumSimulator().Get(); + Assert.Equal("CNOT", op2.GetNonQubitArgumentsAsString()); + } + [Fact] public void QubitTypes() { @@ -58,6 +68,10 @@ public void TupleTypes() Assert.Equal("(\"foo\", (\"bar\", \"car\"))", ("foo", ("bar", "car")).GetNonQubitArgumentsAsString()); Assert.Equal("((\"foo\"), (\"bar\", \"car\"))", (("foo", new FreeQubit(0)), ("bar", "car")).GetNonQubitArgumentsAsString()); + var op = new QuantumSimulator().Get(); + var opTuple = new QTuple<(ICallable, string)>((op, "foo")); + Assert.Equal("(H, \"foo\")", opTuple.GetNonQubitArgumentsAsString()); + var qtuple = new QTuple<(Qubit, string)>((new FreeQubit(0), "foo")); Assert.Equal("(\"foo\")", qtuple.GetNonQubitArgumentsAsString()); } @@ -68,11 +82,18 @@ public void ArrayTypes() Assert.Equal("[1, 2, 3]", new[] { 1, 2, 3 }.GetNonQubitArgumentsAsString()); Assert.Equal("[\"foo\", \"bar\"]", new[] { "foo", "bar" }.GetNonQubitArgumentsAsString()); - var arr = new[] { + var opArr = new ICallable[] { + new QuantumSimulator().Get(), + new QuantumSimulator().Get(), + new QuantumSimulator().Get(), + }; + Assert.Equal("[H, CNOT, Ry]", opArr.GetNonQubitArgumentsAsString()); + + var qTupleArr = new[] { (new FreeQubit(0), "foo"), (new FreeQubit(1), "bar"), }; - Assert.Equal("[(\"foo\"), (\"bar\")]", arr.GetNonQubitArgumentsAsString()); + Assert.Equal("[(\"foo\"), (\"bar\")]", qTupleArr.GetNonQubitArgumentsAsString()); } [Fact] @@ -88,6 +109,10 @@ public void IApplyDataTypes() data = new ApplyData("Foo"); Assert.Equal("\"Foo\"", data.GetNonQubitArgumentsAsString()); + var op = new QuantumSimulator().Get(); + data = new ApplyData(op); + Assert.Equal("H", data.GetNonQubitArgumentsAsString()); + data = new ApplyData>((1, "foo")); Assert.Equal("(1, \"foo\")", data.GetNonQubitArgumentsAsString()); From 161ed8ac3c70e546f9ac71596ca822f33af1a906 Mon Sep 17 00:00:00 2001 From: Andres Paz Date: Wed, 22 Jul 2020 20:41:32 -0700 Subject: [PATCH 02/14] Copy Runtime.dll to build\Release if available on drop. (#315) --- src/Simulation/Native/bootstrap.cmd | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Simulation/Native/bootstrap.cmd b/src/Simulation/Native/bootstrap.cmd index 144b1686a9f..cd32571ecd4 100644 --- a/src/Simulation/Native/bootstrap.cmd +++ b/src/Simulation/Native/bootstrap.cmd @@ -23,6 +23,10 @@ IF EXIST %DROP_FOLDER%\Release\Microsoft.Quantum.Simulator.Runtime.dll copy %DRO IF NOT EXIST %BUILD_FOLDER% mkdir %BUILD_FOLDER% pushd %BUILD_FOLDER% +IF NOT EXIST Release mkdir Release +IF EXIST %DROP_FOLDER%\Release\Microsoft.Quantum.Simulator.Runtime.dll copy %DROP_FOLDER%\Release\Microsoft.Quantum.Simulator.Runtime.dll Release\Microsoft.Quantum.Simulator.Runtime.dll + + cmake -A "x64" ^ -DBUILD_SHARED_LIBS:BOOL="1" ^ .. From 3d335d098d576c571410780e453e85e0f471ef14 Mon Sep 17 00:00:00 2001 From: Raphael Koh Date: Fri, 24 Jul 2020 17:58:57 -0400 Subject: [PATCH 03/14] Make ResetAll a composite operation (#318) --- src/Simulation/QsharpCore/Intrinsic.cs | 12 ++++++++++ .../Simulators.Tests/RuntimeMetadataTests.cs | 24 ++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/Simulation/QsharpCore/Intrinsic.cs b/src/Simulation/QsharpCore/Intrinsic.cs index 76976a0f217..f7bbd4d953b 100644 --- a/src/Simulation/QsharpCore/Intrinsic.cs +++ b/src/Simulation/QsharpCore/Intrinsic.cs @@ -76,4 +76,16 @@ public partial class M return null; } } + + public partial class ResetAll + { + /// + public override RuntimeMetadata? GetRuntimeMetadata(IApplyData args) + { + var metadata = base.GetRuntimeMetadata(args); + if (metadata == null) throw new NullReferenceException($"Null RuntimeMetadata found for {this.ToString()}."); + metadata.IsComposite = true; + return metadata; + } + } } diff --git a/src/Simulation/Simulators.Tests/RuntimeMetadataTests.cs b/src/Simulation/Simulators.Tests/RuntimeMetadataTests.cs index d41b15764fa..a31849fe169 100644 --- a/src/Simulation/Simulators.Tests/RuntimeMetadataTests.cs +++ b/src/Simulation/Simulators.Tests/RuntimeMetadataTests.cs @@ -297,6 +297,28 @@ public void M() Assert.Equal(op.GetRuntimeMetadata(args), expected); } + [Fact] + public void Reset() + { + var target = new FreeQubit(0); + var op = new QuantumSimulator().Get(); + var args = op.__dataIn(target); + var expected = new RuntimeMetadata() + { + Label = "Reset", + FormattedNonQubitArgs = "", + IsAdjoint = false, + IsControlled = false, + IsMeasurement = false, + IsComposite = false, + Children = null, + Controls = new List() { }, + Targets = new List() { target }, + }; + + Assert.Equal(op.GetRuntimeMetadata(args), expected); + } + [Fact] public void ResetAll() { @@ -310,7 +332,7 @@ public void ResetAll() IsAdjoint = false, IsControlled = false, IsMeasurement = false, - IsComposite = false, + IsComposite = true, Children = null, Controls = new List() { }, Targets = targets, From 7d3d0f58914480b23b78cf799a514ae3412092b1 Mon Sep 17 00:00:00 2001 From: Andres Paz Date: Mon, 27 Jul 2020 23:30:41 -0700 Subject: [PATCH 04/14] QDK build improvements. (#317) --- bootstrap.cmd | 14 ------ bootstrap.ps1 | 24 +++++++++ build/build.ps1 | 16 +++--- build/ci.yml | 38 +++++--------- build/manifest.ps1 | 18 +++---- build/steps-init.yml | 8 ++- build/steps-wrap-up.yml | 3 +- build/steps-xplat.yml | 50 ------------------- build/steps.yml | 3 +- build/test.ps1 | 21 ++++---- src/Simulation/Common/Simulators.Dev.props | 19 +++++-- .../CsharpGeneration/FindNuspecReferences.ps1 | 4 +- .../Simulators/FindNuspecReferences.ps1 | 4 +- .../Microsoft.Quantum.Simulators.csproj | 6 --- 14 files changed, 94 insertions(+), 134 deletions(-) create mode 100644 bootstrap.ps1 delete mode 100644 build/steps-xplat.yml diff --git a/bootstrap.cmd b/bootstrap.cmd index bceffe8091f..a7b49e63c01 100644 --- a/bootstrap.cmd +++ b/bootstrap.cmd @@ -12,9 +12,6 @@ git --version || GOTO missingGit :: Initialize C++ runtime project CALL :runtimeBootstrap || EXIT /B 1 -:: Initialize the compiler's nuspec file -CALL :nuspecBootstrap || EXIT /B 1 - :: Next steps are only needed for developers environment, they are skipped for cloud builds. IF NOT "%AGENT_ID%" == "" GOTO EOF @@ -33,17 +30,6 @@ popd EXIT /B -:: Bootstrap the compiler nuspec -:nuspecBootstrap -pushd src\Simulation\CsharpGeneration -CALL powershell -NoProfile .\FindNuspecReferences.ps1 || EXIT /B 1 -popd - -pushd src\Simulation\Simulators -CALL powershell -NoProfile .\FindNuspecReferences.ps1 || EXIT /B 1 -popd -EXIT /B - :missingGit echo. echo This script depends on git. diff --git a/bootstrap.ps1 b/bootstrap.ps1 new file mode 100644 index 00000000000..861a83f3f34 --- /dev/null +++ b/bootstrap.ps1 @@ -0,0 +1,24 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +$ErrorActionPreference = 'Stop' + +Push-Location (Join-Path $PSScriptRoot "src/Simulation/CsharpGeneration") + .\FindNuspecReferences.ps1 +Pop-Location + +Push-Location (Join-Path $PSScriptRoot "src/Simulation/Simulators") + .\FindNuspecReferences.ps1 +Pop-Location + +# bootstrap native folder +if ($Env:ENABLE_NATIVE -ne "false") { + ## Run the right script based on the OS. + if (-not (Test-Path Env:AGENT_OS) -or ($Env:AGENT_OS.StartsWith("Win"))) { + .\bootstrap.cmd + } else { + .\bootstrap.sh + } +} else { + Write-Host "Skipping native. ENABLE_NATIVE variable set to: $Env:ENABLE_NATIVE." +} \ No newline at end of file diff --git a/build/build.ps1 b/build/build.ps1 index 524c0895aa8..73bfd351d01 100644 --- a/build/build.ps1 +++ b/build/build.ps1 @@ -6,14 +6,18 @@ $ErrorActionPreference = 'Stop' & "$PSScriptRoot/set-env.ps1" $all_ok = $True -Write-Host "##[info]Build Native simulator" -cmake --build (Join-Path $PSScriptRoot "../src/Simulation/Native/build") --config $Env:BUILD_CONFIGURATION -if ($LastExitCode -ne 0) { - Write-Host "##vso[task.logissue type=error;]Failed to build Native simulator." - $script:all_ok = $False +if ($Env:ENABLE_NATIVE -ne "false") { + Write-Host "##[info]Build Native simulator" + $nativeBuild = (Join-Path $PSScriptRoot "../src/Simulation/Native/build") + cmake --build $nativeBuild --config $Env:BUILD_CONFIGURATION + if ($LastExitCode -ne 0) { + Write-Host "##vso[task.logissue type=error;]Failed to build Native simulator." + $script:all_ok = $False + } +} else { + Write-Host "Skipping native. ENABLE_NATIVE variable set to: $Env:ENABLE_NATIVE." } - function Build-One { param( [string]$action, diff --git a/build/ci.yml b/build/ci.yml index dc1942468d3..b274f861d26 100644 --- a/build/ci.yml +++ b/build/ci.yml @@ -9,34 +9,22 @@ variables: Drop.Native: $(System.DefaultWorkingDirectory)/xplat jobs: -- job: macOS - pool: - vmImage: 'macOS-latest' - steps: - - template: steps-xplat.yml - +- job: build + displayName: Build + strategy: + matrix: + linux: + imageName: 'ubuntu-latest' + mac: + imageName: 'macOS-latest' + windows: + imageName: 'windows-latest' + pool: + vmImage: $(imageName) -- job: Linux - pool: - vmImage: 'ubuntu-latest' steps: - - template: steps-xplat.yml - - -- job: Windows - pool: - vmImage: 'windows-2019' - dependsOn: - - macOS - - Linux - condition: succeeded() - steps: - - task: DownloadBuildArtifacts@0 - displayName: 'Download xplat native binaries' - inputs: - artifactName: xplat - downloadPath: $(System.DefaultWorkingDirectory) - template: steps.yml + - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 displayName: 'Component Detection' inputs: diff --git a/build/manifest.ps1 b/build/manifest.ps1 index 29ea070beb7..147f234a98c 100644 --- a/build/manifest.ps1 +++ b/build/manifest.ps1 @@ -16,15 +16,15 @@ ); Assemblies = @( ".\src\Azure\Azure.Quantum.Client\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Azure.Quantum.Client.dll", - ".\src\simulation\CsharpGeneration\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.CsharpGeneration.dll", - ".\src\simulation\CsharpGeneration.App\bin\$Env:BUILD_CONFIGURATION\netcoreapp3.1\Microsoft.Quantum.CsharpGeneration.App.dll", - ".\src\simulation\CsharpGeneration.App\bin\$Env:BUILD_CONFIGURATION\netcoreapp3.1\Microsoft.Quantum.RoslynWrapper.dll", - ".\src\simulation\Core\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.Runtime.Core.dll", - ".\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\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\CsharpGeneration\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.CsharpGeneration.dll", + ".\src\Simulation\CsharpGeneration.App\bin\$Env:BUILD_CONFIGURATION\netcoreapp3.1\Microsoft.Quantum.CsharpGeneration.App.dll", + ".\src\Simulation\CsharpGeneration.App\bin\$Env:BUILD_CONFIGURATION\netcoreapp3.1\Microsoft.Quantum.RoslynWrapper.dll", + ".\src\Simulation\Core\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.Runtime.Core.dll", + ".\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\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\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/steps-init.yml b/build/steps-init.yml index 6c5d681bae7..694ba89302a 100644 --- a/build/steps-init.yml +++ b/build/steps-init.yml @@ -18,8 +18,6 @@ steps: ## # Bootstrap ## -- task: BatchScript@1 - displayName: 'Prepare build' - inputs: - filename: bootstrap.cmd - modifyEnvironment: true +- pwsh: ./bootstrap.ps1 + displayName: "Bootstrap repository" + workingDirectory: $(System.DefaultWorkingDirectory) diff --git a/build/steps-wrap-up.yml b/build/steps-wrap-up.yml index fb36f7194b8..9cf3a9957fc 100644 --- a/build/steps-wrap-up.yml +++ b/build/steps-wrap-up.yml @@ -12,7 +12,8 @@ steps: testRunTitle: 'Q# runtime tests' - task: PublishSymbols@1 - displayName: 'Publish symbols' + displayName: 'Publish symbols (Windows only)' + condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT')) continueOnError: true inputs: SearchPattern: '$(System.DefaultWorkingDirectory)/src/**/*.pdb' diff --git a/build/steps-xplat.yml b/build/steps-xplat.yml deleted file mode 100644 index 0af6e6d1300..00000000000 --- a/build/steps-xplat.yml +++ /dev/null @@ -1,50 +0,0 @@ -## -# xplat Native Simulator build -## -steps: - -- task: UseDotNet@2 - displayName: 'Use .NET Core SDK 3.1.100' - inputs: - packageType: sdk - version: '3.1.100' - - -- bash: ./bootstrap.sh - displayName: "Bootstrap repository" - workingDirectory: $(System.DefaultWorkingDirectory) - - -- powershell: ./build.ps1 - displayName: "Building Q# runtime" - workingDirectory: $(System.DefaultWorkingDirectory)/build - - -- powershell: ./test.ps1 - displayName: "Testing Q# runtime" - workingDirectory: $(System.DefaultWorkingDirectory)/build - condition: and(succeeded(), ne(variables['Skip.Tests'], 'true')) - - -- task: CopyFiles@2 - displayName: 'Copy Files to: artifact staging directory' - inputs: - SourceFolder: '$(System.DefaultWorkingDirectory)' - Contents: 'src/Simulation/Native/build/**' - TargetFolder: '$(Build.ArtifactStagingDirectory)' - - -- task: PublishTestResults@2 - displayName: 'Publish tests results' - condition: succeededOrFailed() - inputs: - testResultsFormat: VSTest - testResultsFiles: '$(System.DefaultWorkingDirectory)/**/*.trx' - testRunTitle: 'Q# xplat runtime tests' - - -- task: PublishBuildArtifacts@1 - displayName: 'Publish Artifact: xplat' - inputs: - PathtoPublish: '$(Build.ArtifactStagingDirectory)' - artifactName: xplat diff --git a/build/steps.yml b/build/steps.yml index 3b45dddd9eb..87da999f9e3 100644 --- a/build/steps.yml +++ b/build/steps.yml @@ -23,7 +23,8 @@ steps: - powershell: ./pack.ps1 - displayName: "Pack Q# runtime" + displayName: "Pack Q# runtime (Windows only)" + condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT')) workingDirectory: $(System.DefaultWorkingDirectory)/build diff --git a/build/test.ps1 b/build/test.ps1 index f66c42e0ad1..09e0e49fb9f 100644 --- a/build/test.ps1 +++ b/build/test.ps1 @@ -4,16 +4,19 @@ & "$PSScriptRoot/set-env.ps1" $all_ok = $True -Write-Host "##[info]Test Native simulator" -pushd (Join-Path $PSScriptRoot "../src/Simulation/Native/build") -cmake --build . --config $Env:BUILD_CONFIGURATION -ctest -C $Env:BUILD_CONFIGURATION -if ($LastExitCode -ne 0) { - Write-Host "##vso[task.logissue type=error;]Failed to test Native Simulator" - $script:all_ok = $False +if ($Env:ENABLE_NATIVE -ne "false") { + Write-Host "##[info]Test Native simulator" + pushd (Join-Path $PSScriptRoot "../src/Simulation/Native/build") + cmake --build . --config $Env:BUILD_CONFIGURATION + ctest -C $Env:BUILD_CONFIGURATION + if ($LastExitCode -ne 0) { + Write-Host "##vso[task.logissue type=error;]Failed to test Native Simulator" + $script:all_ok = $False + } + popd +} else { + Write-Host "Skipping native. ENABLE_NATIVE variable set to: $Env:ENABLE_NATIVE." } -popd - function Test-One { Param($project) diff --git a/src/Simulation/Common/Simulators.Dev.props b/src/Simulation/Common/Simulators.Dev.props index 2c93b5ab65e..7c44b437a38 100644 --- a/src/Simulation/Common/Simulators.Dev.props +++ b/src/Simulation/Common/Simulators.Dev.props @@ -5,14 +5,17 @@ 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) + $(QsimDllMac) + $(QsimDllLinux) + $(QsimDllWindowsRelease) + $(QsimDllWindowsDebug) @@ -23,6 +26,14 @@ + + + Microsoft.Quantum.Simulator.Runtime.dll + PreserveNewest + false + + + diff --git a/src/Simulation/CsharpGeneration/FindNuspecReferences.ps1 b/src/Simulation/CsharpGeneration/FindNuspecReferences.ps1 index 0c3695812f9..f669dac1860 100644 --- a/src/Simulation/CsharpGeneration/FindNuspecReferences.ps1 +++ b/src/Simulation/CsharpGeneration/FindNuspecReferences.ps1 @@ -21,13 +21,13 @@ using namespace System.IO -$target = 'Microsoft.Quantum.CsharpGeneration.nuspec' +$target = Join-Path $PSScriptRoot 'Microsoft.Quantum.CsharpGeneration.nuspec' if (Test-Path $target) { Write-Host "$target exists. Skipping generating new one." exit } -$nuspec = [Xml](Get-Content 'Microsoft.Quantum.CsharpGeneration.nuspec.template') +$nuspec = [Xml](Get-Content (Join-Path $PSScriptRoot 'Microsoft.Quantum.CsharpGeneration.nuspec.template')) $dependencies = $nuspec.CreateElement('dependencies', $nuspec.package.metadata.NamespaceURI) # Adds a dependency to the dependencies element if it does not already exist. diff --git a/src/Simulation/Simulators/FindNuspecReferences.ps1 b/src/Simulation/Simulators/FindNuspecReferences.ps1 index a1fd46b8f2b..993f4b0948e 100644 --- a/src/Simulation/Simulators/FindNuspecReferences.ps1 +++ b/src/Simulation/Simulators/FindNuspecReferences.ps1 @@ -19,7 +19,7 @@ # nuget is tracking this problem at: https://github.com/NuGet/Home/issues/4491 ######################################## -$target = "Microsoft.Quantum.Simulators.nuspec" +$target = Join-Path $PSScriptRoot "Microsoft.Quantum.Simulators.nuspec" if (Test-Path $target) { Write-Host "$target exists. Skipping generating new one." @@ -28,7 +28,7 @@ if (Test-Path $target) { # Start with the nuspec template -$nuspec = [xml](Get-Content "Microsoft.Quantum.Simulators.nuspec.template") +$nuspec = [xml](Get-Content (Join-Path $PSScriptRoot "Microsoft.Quantum.Simulators.nuspec.template")) $dep = $nuspec.CreateElement('dependencies', $nuspec.package.metadata.NamespaceURI) function Add-PackageReferenceIfNew($ref) diff --git a/src/Simulation/Simulators/Microsoft.Quantum.Simulators.csproj b/src/Simulation/Simulators/Microsoft.Quantum.Simulators.csproj index 50eef571a8b..98541863364 100644 --- a/src/Simulation/Simulators/Microsoft.Quantum.Simulators.csproj +++ b/src/Simulation/Simulators/Microsoft.Quantum.Simulators.csproj @@ -25,12 +25,6 @@ - - Microsoft.Quantum.Simulator.Runtime.dll - PreserveNewest - false - - runtimes\win-x64\native\%(RecursiveDir)%(FileName)%(Extension) PreserveNewest From 0fbdeab5cb50823b011e7878e4fa0188397f6ce6 Mon Sep 17 00:00:00 2001 From: Chris Granade Date: Tue, 28 Jul 2020 09:34:02 -0700 Subject: [PATCH 05/14] Make MaybeDisplayDiagnostic public. (#319) --- src/Simulation/Common/SimulatorBase.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Simulation/Common/SimulatorBase.cs b/src/Simulation/Common/SimulatorBase.cs index 41f566ea641..7d216c00edf 100644 --- a/src/Simulation/Common/SimulatorBase.cs +++ b/src/Simulation/Common/SimulatorBase.cs @@ -196,7 +196,10 @@ public void EnableExceptionPrinting() /// no guarantee is made as to any particular action taken as a result /// of calling this method. /// - protected void MaybeDisplayDiagnostic(object data) + /// + /// The diagnostic object to be displayed. + /// + public void MaybeDisplayDiagnostic(object data) { OnDisplayableDiagnostic?.Invoke(data); } From 8d6007590d2f136b425ad9ca6d43a6ca1cb47bcf Mon Sep 17 00:00:00 2001 From: Sasha <35849227+avasch01@users.noreply.github.com> Date: Tue, 4 Aug 2020 16:43:18 -0700 Subject: [PATCH 06/14] EncourageReuse option in QubitManager. (#320) * EncourageReuse option in QubitManager. Currently Qubit Manager tries to reuse released qubits as soon as possible and prefers it to allocating fresh unused ones. This is good for some scenarios, however, in other scenarios it may be preferrable to first allocate fresh unused qubits, and only then try to reuse released ones (oldest released first). Both behaviors are now possible via a backwards-compatible optional parameter in QubitManager constructor. * Review feedback * . --- src/Simulation/Common/QubitManager.cs | 37 +++++++- .../Common/QubitManagerTrackingScope.cs | 8 +- .../Simulators.Tests/QubitManagerTests.cs | 85 +++++++++++++++++++ 3 files changed, 125 insertions(+), 5 deletions(-) diff --git a/src/Simulation/Common/QubitManager.cs b/src/Simulation/Common/QubitManager.cs index bd19bdad338..a70651f5059 100644 --- a/src/Simulation/Common/QubitManager.cs +++ b/src/Simulation/Common/QubitManager.cs @@ -5,6 +5,7 @@ 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; @@ -25,11 +26,13 @@ public class QubitManager long AllocatedForBorrowing; // All qubits allocated only for borrowing, will be marked with this number or higher. long[] qubits; // Tracks the allocation state of all qubits. long free; // Points to the first free (unallocated) qubit. + long freeTail; // Points to the last free (unallocated) qubit. Only valid iff (!EncourageReuse). long numAllocatedQubits; // Tracking this for optimization. long numDisabledQubits; // Number of disabled qubits. // Options bool MayExtendCapacity; + bool EncourageReuse; public bool DisableBorrowing { get; } const long MaxQubitCapacity = long.MaxValue - 3; @@ -49,9 +52,14 @@ public class QubitManager /// /// Creates and initializes QubitManager that can handle up to numQubits qubits /// - public QubitManager(long qubitCapacity, bool mayExtendCapacity = false, bool disableBorrowing = false) + public QubitManager( + long qubitCapacity, + bool mayExtendCapacity = false, + bool disableBorrowing = false, + bool encourageReuse = true) { MayExtendCapacity = mayExtendCapacity; + EncourageReuse = encourageReuse; DisableBorrowing = disableBorrowing; if (qubitCapacity <= 0) { qubitCapacity = MinQubitCapacity; } @@ -65,6 +73,7 @@ public QubitManager(long qubitCapacity, bool mayExtendCapacity = false, bool dis Debug.Assert(this.qubits[NumQubits - 1] == None); free = 0; + freeTail = NumQubits - 1; numAllocatedQubits = 0; numDisabledQubits = 0; } @@ -121,6 +130,7 @@ private void ExtendQubitArray() if (free == oldNone) { free = oldNumQubits; + freeTail = NumQubits - 1; } else { Debug.Assert(false, "Why do we extend an array, when we still have available slots?"); @@ -300,8 +310,29 @@ protected virtual void ReleaseOneQubit(Qubit qubit, bool usedOnlyForBorrowing) { throw new ArgumentException("Attempt to free qubit that has not been allocated."); } - qubits[qubit.Id] = free; - free = qubit.Id; + if (EncourageReuse) { + qubits[qubit.Id] = free; + free = qubit.Id; + } + else + { + // If we are allowed to extend capacity we will never reuse this qubit, + // otherwise we need to add it to the free qubits list. + if (!MayExtendCapacity) + { + if (qubits[freeTail] != None) + { + // There were no free qubits at all + free = qubit.Id; + } + else + { + qubits[freeTail] = qubit.Id; + } + } + qubits[qubit.Id] = None; + freeTail = qubit.Id; + } numAllocatedQubits--; Debug.Assert(numAllocatedQubits >= 0); diff --git a/src/Simulation/Common/QubitManagerTrackingScope.cs b/src/Simulation/Common/QubitManagerTrackingScope.cs index 23f654439de..a166f98bfa0 100644 --- a/src/Simulation/Common/QubitManagerTrackingScope.cs +++ b/src/Simulation/Common/QubitManagerTrackingScope.cs @@ -44,8 +44,12 @@ public List Locals private Stack operationStack; // Stack of operation calls. private StackFrame curFrame; // Current stack frame - all qubits in current scope are listed here. - public QubitManagerTrackingScope(long qubitCapacity, bool mayExtendCapacity = false, bool disableBorrowing = false) - : base(qubitCapacity, mayExtendCapacity, disableBorrowing) + public QubitManagerTrackingScope( + long qubitCapacity, + bool mayExtendCapacity = false, + bool disableBorrowing = false, + bool encourageReuse = true) + : base(qubitCapacity, mayExtendCapacity, disableBorrowing, encourageReuse) { if (!DisableBorrowing) { diff --git a/src/Simulation/Simulators.Tests/QubitManagerTests.cs b/src/Simulation/Simulators.Tests/QubitManagerTests.cs index a5f2123d0f2..8ee972883a8 100644 --- a/src/Simulation/Simulators.Tests/QubitManagerTests.cs +++ b/src/Simulation/Simulators.Tests/QubitManagerTests.cs @@ -152,6 +152,91 @@ public void TestQubitManager() } } + /// + /// Test for QubitManager. + /// + [Fact] + public void TestQubitManagerDiscouragingReuse() + { + { // BLOCK testing mayExtendCapacity:false + QubitManager qm = new QubitManager(10, mayExtendCapacity: false, disableBorrowing: false, encourageReuse: false); + + // Test allocation of single qubit + Qubit q1 = qm.Allocate(); + Assert.True(q1.Id == 0); + + // Test allocation of multiple qubits + IQArray qa1 = qm.Allocate(4); + Assert.True(qa1.Length == 4); + Assert.True(qa1[0].Id == 1); + Assert.True(qa1[1].Id == 2); + Assert.True(qa1[2].Id == 3); + Assert.True(qa1[3].Id == 4); + + // Test reuse of deallocated qubits + qm.Release(qa1[1]); + + Qubit q2 = qm.Allocate(); + Assert.True(q2.Id == 5); + + IQArray qa2 = qm.Allocate(3); + Assert.True(qa2.Length == 3); + Assert.True(qa2[0].Id == 6); + Assert.True(qa2[1].Id == 7); + Assert.True(qa2[2].Id == 8); + + qm.Release(qa2); + + Qubit q3 = qm.Allocate(); + Assert.True(q3.Id == 9); + + Qubit q4 = qm.Allocate(); + Assert.True(q4.Id == 2); + + Qubit q5 = qm.Allocate(); + Assert.True(q5.Id == 8); + } + + { // BLOCK testing mayExtendCapacity:true + QubitManager qm = new QubitManager(10, mayExtendCapacity: true, disableBorrowing: false, encourageReuse: false); + + // Test allocation of single qubit + Qubit q1 = qm.Allocate(); + Assert.True(q1.Id == 0); + + // Test allocation of multiple qubits + IQArray qa1 = qm.Allocate(4); + Assert.True(qa1.Length == 4); + Assert.True(qa1[0].Id == 1); + Assert.True(qa1[1].Id == 2); + Assert.True(qa1[2].Id == 3); + Assert.True(qa1[3].Id == 4); + + // Test reuse of deallocated qubits + qm.Release(qa1[1]); + + Qubit q2 = qm.Allocate(); + Assert.True(q2.Id == 5); + + IQArray qa2 = qm.Allocate(3); + Assert.True(qa2.Length == 3); + Assert.True(qa2[0].Id == 6); + Assert.True(qa2[1].Id == 7); + Assert.True(qa2[2].Id == 8); + + qm.Release(qa2); + + Qubit q3 = qm.Allocate(); + Assert.True(q3.Id == 9); + + Qubit q4 = qm.Allocate(); + Assert.True(q4.Id == 10); + + Qubit q5 = qm.Allocate(); + Assert.True(q5.Id == 11); + } + } + /// /// Test for QubitManagerTrackingScope. /// From b87c1c54121436f6389821e5eeccd8c7657ce90d Mon Sep 17 00:00:00 2001 From: Raphael Koh Date: Mon, 10 Aug 2020 18:15:55 -0400 Subject: [PATCH 07/14] Remove duplicate qubits from RuntimeMetadata.Targets (#324) --- src/Simulation/Core/Operations/Operation.cs | 14 +++++------ .../Circuits/RuntimeMetadataTest.qs | 4 +++ .../Simulators.Tests/RuntimeMetadataTests.cs | 25 +++++++++++++++++++ 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/Simulation/Core/Operations/Operation.cs b/src/Simulation/Core/Operations/Operation.cs index aba000d7765..6a20d69af6c 100644 --- a/src/Simulation/Core/Operations/Operation.cs +++ b/src/Simulation/Core/Operations/Operation.cs @@ -16,7 +16,7 @@ public partial interface ICallable : ICallable { O Apply(I args); - ICallable Partial

(Func mapper); + ICallable Partial

(Func mapper); } ///

@@ -34,7 +34,7 @@ public interface IOperationWrapper /// /// Type of input parameters. /// Type of return values. - [DebuggerTypeProxy(typeof(Operation<,>.DebuggerProxy))] + [DebuggerTypeProxy(typeof(Operation<,>.DebuggerProxy))] public abstract class Operation : AbstractCallable, ICallable { private Lazy> _adjoint; @@ -56,7 +56,7 @@ public Operation(IOperationFactory m) : base(m) public virtual IApplyData __dataIn(I data) => new QTuple(data); - + public virtual IApplyData __dataOut(O data) => new QTuple(data); [DebuggerBrowsable(DebuggerBrowsableState.Never)] @@ -83,7 +83,7 @@ public Operation(IOperationFactory m) : base(m) { Label = ((ICallable)this).Name, FormattedNonQubitArgs = args.GetNonQubitArgumentsAsString() ?? "", - Targets = args.GetQubits() ?? new List(), + Targets = args.GetQubits()?.Distinct() ?? new List(), }; public O Apply(I a) @@ -95,7 +95,7 @@ public O Apply(I a) this.Factory?.StartOperation(this, __dataIn(a)); __result__ = this.Body(a); } - catch( Exception e) + catch (Exception e) { this.Factory?.Fail(System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(e)); throw; @@ -105,7 +105,7 @@ public O Apply(I a) this.Factory?.EndOperation(this, __dataOut(__result__)); } - return __result__; + return __result__; } public T Partial(object partialInfo) @@ -212,7 +212,7 @@ internal class DebuggerProxy { private Operation op; - public DebuggerProxy(Operation op) + public DebuggerProxy(Operation op) { this.op = op; } diff --git a/src/Simulation/Simulators.Tests/Circuits/RuntimeMetadataTest.qs b/src/Simulation/Simulators.Tests/Circuits/RuntimeMetadataTest.qs index b75e70fb7d5..4e721723832 100644 --- a/src/Simulation/Simulators.Tests/Circuits/RuntimeMetadataTest.qs +++ b/src/Simulation/Simulators.Tests/Circuits/RuntimeMetadataTest.qs @@ -26,5 +26,9 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits { HOp(q); } } + + operation TwoQubitOp (q1 : Qubit, q2 : Qubit) : Unit { + // ... + } } diff --git a/src/Simulation/Simulators.Tests/RuntimeMetadataTests.cs b/src/Simulation/Simulators.Tests/RuntimeMetadataTests.cs index a31849fe169..e9f6e69e626 100644 --- a/src/Simulation/Simulators.Tests/RuntimeMetadataTests.cs +++ b/src/Simulation/Simulators.Tests/RuntimeMetadataTests.cs @@ -409,7 +409,10 @@ public void MResetZ() Assert.Equal(op.GetRuntimeMetadata(args), expected); } + } + public class CustomCircuitTests + { [Fact] public void EmptyOperation() { @@ -475,6 +478,28 @@ public void NestedOperation() Assert.Equal(op.GetRuntimeMetadata(args), expected); } + + [Fact] + public void DuplicateQubitArgs() + { + var q = new FreeQubit(0); + var op = new QuantumSimulator().Get(); + var args = op.__dataIn((q, q)); + var expected = new RuntimeMetadata() + { + Label = "TwoQubitOp", + FormattedNonQubitArgs = "", + IsAdjoint = false, + IsControlled = false, + IsMeasurement = false, + IsComposite = false, + Children = null, + Controls = new List() { }, + Targets = new List() { q }, + }; + + Assert.Equal(op.GetRuntimeMetadata(args), expected); + } } public class UDTTests From 38d00d1a7380592eac9530c63989c1ada42cb18d Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Thu, 13 Aug 2020 10:46:18 -0700 Subject: [PATCH 08/14] Fix asserts in QubitManager (#332) * Fix asserts in QubitManager * Remove asserts from QubitManager --- src/Simulation/Common/QubitManager.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Simulation/Common/QubitManager.cs b/src/Simulation/Common/QubitManager.cs index a70651f5059..9bc54dfce3d 100644 --- a/src/Simulation/Common/QubitManager.cs +++ b/src/Simulation/Common/QubitManager.cs @@ -104,7 +104,6 @@ private void ExtendQubitArray() { if (oldQubitsArray[i] == oldNone) { // Point to the first new (free) element - Debug.Assert(false,"Why do we extend an array, when we still have available slots?"); this.qubits[i] = oldNumQubits; } else if (oldQubitsArray[i] == oldAllocated) { // Allocated qubits are marked differently now. @@ -131,9 +130,6 @@ private void ExtendQubitArray() { free = oldNumQubits; freeTail = NumQubits - 1; - } else - { - Debug.Assert(false, "Why do we extend an array, when we still have available slots?"); } } From 477dfa854ce769e72ae2f0dd45fea1ed38ce3503 Mon Sep 17 00:00:00 2001 From: bettinaheim <34236215+bettinaheim@users.noreply.github.com> Date: Thu, 13 Aug 2020 15:24:50 -0700 Subject: [PATCH 09/14] Use processor architecture to determine what code needs to be generated (#331) --- .gitignore | 1 + Simulation.sln | 19 ++++++++ .../SimulationCodeTests.fs | 2 +- src/Simulation/CsharpGeneration/Context.fs | 7 ++- .../Microsoft.Quantum.CsharpGeneration.fsproj | 2 +- .../CsharpGeneration/SimulationCode.fs | 2 +- ....Simulation.QCTraceSimulatorRuntime.csproj | 2 +- .../Microsoft.Quantum.QSharp.Core.csproj | 2 +- src/Simulation/Simulators.Tests/CoreTests.cs | 14 ++++++ .../HoneywellExe/HoneywellExe.csproj | 2 +- .../TestProjects/IonQExe/IonQExe.csproj | 48 +++++++++---------- .../Library with Spaces.csproj | 6 +-- .../TestProjects/Library1/Library1.csproj | 2 +- .../TestProjects/Library2/Library2.csproj | 2 +- .../TestProjects/QCIExe/QCIExe.csproj | 48 +++++++++---------- .../TestProjects/QsharpExe/QsharpExe.csproj | 2 +- .../TestProjects/TargetedExe/Program.qs | 16 +++++++ .../TargetedExe/TargetedExe.csproj | 40 ++++++++++++++++ .../TestProjects/UnitTests/UnitTests.csproj | 2 +- .../Tests.Microsoft.Quantum.Simulators.csproj | 9 +++- .../Microsoft.Quantum.Simulators.csproj | 2 +- 21 files changed, 165 insertions(+), 65 deletions(-) create mode 100644 src/Simulation/Simulators.Tests/TestProjects/TargetedExe/Program.qs create mode 100644 src/Simulation/Simulators.Tests/TestProjects/TargetedExe/TargetedExe.csproj diff --git a/.gitignore b/.gitignore index 754c9b65976..354f05b9d0d 100644 --- a/.gitignore +++ b/.gitignore @@ -336,3 +336,4 @@ ASALocalRun/ # MFractors (Xamarin productivity tool) working folder .mfractor/ /src/Simulation/Simulators.Tests/TestProjects/QsharpExe/built +/src/Simulation/Simulators.Tests/TestProjects/TargetedExe/built diff --git a/Simulation.sln b/Simulation.sln index b22a08046ff..045a3b2c1dc 100644 --- a/Simulation.sln +++ b/Simulation.sln @@ -63,6 +63,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IonQExe", "src\Simulation\S EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QCIExe", "src\Simulation\Simulators.Tests\TestProjects\QCIExe\QCIExe.csproj", "{C015FF41-9A51-4AF0-AEFC-2547D596B10A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TargetedExe", "src\Simulation\Simulators.Tests\TestProjects\TargetedExe\TargetedExe.csproj", "{D292BF18-3956-4827-820E-254C3F81EF09}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -459,6 +461,22 @@ Global {C015FF41-9A51-4AF0-AEFC-2547D596B10A}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU {C015FF41-9A51-4AF0-AEFC-2547D596B10A}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU {C015FF41-9A51-4AF0-AEFC-2547D596B10A}.RelWithDebInfo|x64.Build.0 = Release|Any CPU + {D292BF18-3956-4827-820E-254C3F81EF09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D292BF18-3956-4827-820E-254C3F81EF09}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D292BF18-3956-4827-820E-254C3F81EF09}.Debug|x64.ActiveCfg = Debug|Any CPU + {D292BF18-3956-4827-820E-254C3F81EF09}.Debug|x64.Build.0 = Debug|Any CPU + {D292BF18-3956-4827-820E-254C3F81EF09}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU + {D292BF18-3956-4827-820E-254C3F81EF09}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU + {D292BF18-3956-4827-820E-254C3F81EF09}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU + {D292BF18-3956-4827-820E-254C3F81EF09}.MinSizeRel|x64.Build.0 = Debug|Any CPU + {D292BF18-3956-4827-820E-254C3F81EF09}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D292BF18-3956-4827-820E-254C3F81EF09}.Release|Any CPU.Build.0 = Release|Any CPU + {D292BF18-3956-4827-820E-254C3F81EF09}.Release|x64.ActiveCfg = Release|Any CPU + {D292BF18-3956-4827-820E-254C3F81EF09}.Release|x64.Build.0 = Release|Any CPU + {D292BF18-3956-4827-820E-254C3F81EF09}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU + {D292BF18-3956-4827-820E-254C3F81EF09}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU + {D292BF18-3956-4827-820E-254C3F81EF09}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU + {D292BF18-3956-4827-820E-254C3F81EF09}.RelWithDebInfo|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -489,6 +507,7 @@ Global {1448512E-132F-4DA8-BCBA-D98F16B31600} = {09C842CB-930C-4C7D-AD5F-E30DE4A55820} {55833C6C-6E91-4413-9F77-96B3A09666B8} = {09C842CB-930C-4C7D-AD5F-E30DE4A55820} {C015FF41-9A51-4AF0-AEFC-2547D596B10A} = {09C842CB-930C-4C7D-AD5F-E30DE4A55820} + {D292BF18-3956-4827-820E-254C3F81EF09} = {09C842CB-930C-4C7D-AD5F-E30DE4A55820} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {929C0464-86D8-4F70-8835-0A5EAF930821} diff --git a/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs b/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs index de97e3aedc8..12605ed0603 100644 --- a/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs +++ b/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs @@ -2335,7 +2335,7 @@ namespace N1 let testOneClass (_,op : QsCallable) executionTarget (expected : string) = let expected = expected.Replace("%%%", HttpUtility.JavaScriptStringEncode op.SourceFile.Value) let assemblyConstants = - new System.Collections.Generic.KeyValuePair<_,_> (AssemblyConstants.ExecutionTarget, executionTarget) + new Collections.Generic.KeyValuePair<_,_> (AssemblyConstants.ProcessorArchitecture, executionTarget) |> Seq.singleton |> ImmutableDictionary.CreateRange let compilation = {Namespaces = syntaxTree; EntryPoints = ImmutableArray.Create op.FullName} diff --git a/src/Simulation/CsharpGeneration/Context.fs b/src/Simulation/CsharpGeneration/Context.fs index db612b799c3..fa80c982c4f 100644 --- a/src/Simulation/CsharpGeneration/Context.fs +++ b/src/Simulation/CsharpGeneration/Context.fs @@ -104,6 +104,11 @@ type CodegenContext = { static member public Create (syntaxTree : ImmutableArray) = CodegenContext.Create(syntaxTree, ImmutableDictionary.Empty) + member public this.ProcessorArchitecture = + match this.assemblyConstants.TryGetValue AssemblyConstants.ProcessorArchitecture with + | true, name -> name + | false, _ -> null + member public this.ExecutionTarget = match this.assemblyConstants.TryGetValue AssemblyConstants.ExecutionTarget with | true, name -> name @@ -116,7 +121,7 @@ type CodegenContext = { member internal this.GenerateCodeForSource (fileName : NonNullable) = let targetsQuantumProcessor = - match this.assemblyConstants.TryGetValue AssemblyConstants.ExecutionTarget with + match this.assemblyConstants.TryGetValue AssemblyConstants.ProcessorArchitecture with | true, target -> target = AssemblyConstants.HoneywellProcessor || target = AssemblyConstants.IonQProcessor || target = AssemblyConstants.QCIProcessor | _ -> false not (fileName.Value.EndsWith ".dll") || targetsQuantumProcessor diff --git a/src/Simulation/CsharpGeneration/Microsoft.Quantum.CsharpGeneration.fsproj b/src/Simulation/CsharpGeneration/Microsoft.Quantum.CsharpGeneration.fsproj index 59d46b17145..dddbbf8c3bb 100644 --- a/src/Simulation/CsharpGeneration/Microsoft.Quantum.CsharpGeneration.fsproj +++ b/src/Simulation/CsharpGeneration/Microsoft.Quantum.CsharpGeneration.fsproj @@ -21,7 +21,7 @@ - + diff --git a/src/Simulation/CsharpGeneration/SimulationCode.fs b/src/Simulation/CsharpGeneration/SimulationCode.fs index 30d8bcdd95a..15dfcdf5dfd 100644 --- a/src/Simulation/CsharpGeneration/SimulationCode.fs +++ b/src/Simulation/CsharpGeneration/SimulationCode.fs @@ -927,7 +927,7 @@ module SimulationCode = /// Returns a static property of type OperationInfo using the operation's input and output types. let buildOperationInfoProperty (globalContext:CodegenContext) operationInput operationOutput operationName = let propertyType = - match globalContext.ExecutionTarget with + match globalContext.ProcessorArchitecture with | target when target = AssemblyConstants.HoneywellProcessor -> sprintf "HoneywellEntryPointInfo<%s, %s>" operationInput operationOutput | target when target = AssemblyConstants.IonQProcessor -> sprintf "IonQEntryPointInfo<%s, %s>" operationInput operationOutput | target when target = AssemblyConstants.QCIProcessor -> sprintf "QCIEntryPointInfo<%s, %s>" operationInput operationOutput diff --git a/src/Simulation/QCTraceSimulator.Tests/Tests.Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.csproj b/src/Simulation/QCTraceSimulator.Tests/Tests.Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.csproj index 4bbaca22c96..74cf526a2da 100644 --- a/src/Simulation/QCTraceSimulator.Tests/Tests.Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.csproj +++ b/src/Simulation/QCTraceSimulator.Tests/Tests.Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.csproj @@ -1,4 +1,4 @@ - + diff --git a/src/Simulation/QsharpCore/Microsoft.Quantum.QSharp.Core.csproj b/src/Simulation/QsharpCore/Microsoft.Quantum.QSharp.Core.csproj index 93ea0e58438..d6c929018e1 100644 --- a/src/Simulation/QsharpCore/Microsoft.Quantum.QSharp.Core.csproj +++ b/src/Simulation/QsharpCore/Microsoft.Quantum.QSharp.Core.csproj @@ -1,4 +1,4 @@ - + diff --git a/src/Simulation/Simulators.Tests/CoreTests.cs b/src/Simulation/Simulators.Tests/CoreTests.cs index 185351df696..88917ff4c24 100644 --- a/src/Simulation/Simulators.Tests/CoreTests.cs +++ b/src/Simulation/Simulators.Tests/CoreTests.cs @@ -43,6 +43,20 @@ public void BasicExecution() Assert.Empty(error.ToString().Trim()); } + [Fact] + public void BasicExecutionTargetedExe() + { + var asmPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + var exe = Path.Combine(asmPath, "TestTargetedExe", "TargetedExe.dll"); + + ProcessRunner.Run("dotnet", exe, out StringBuilder output, out StringBuilder error, out int exitCode, out Exception ex); + + Assert.Null(ex); + Assert.Equal(0, exitCode); + Assert.Empty(error.ToString().Trim()); + Assert.Equal("TargetedExe", output.ToString().Trim()); + } + [Fact] public void Borrowing() { diff --git a/src/Simulation/Simulators.Tests/TestProjects/HoneywellExe/HoneywellExe.csproj b/src/Simulation/Simulators.Tests/TestProjects/HoneywellExe/HoneywellExe.csproj index 4e966759f8d..2556f1ae507 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/HoneywellExe/HoneywellExe.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/HoneywellExe/HoneywellExe.csproj @@ -1,4 +1,4 @@ - + Library diff --git a/src/Simulation/Simulators.Tests/TestProjects/IonQExe/IonQExe.csproj b/src/Simulation/Simulators.Tests/TestProjects/IonQExe/IonQExe.csproj index c9278c38294..c625e48ab23 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/IonQExe/IonQExe.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/IonQExe/IonQExe.csproj @@ -1,25 +1,25 @@ - - - - Library - netcoreapp3.1 - - false - false - false - true - ionq.qpu - - - - - - - - - - - - - + + + + Library + netcoreapp3.1 + + false + false + false + true + ionq.qpu + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Simulation/Simulators.Tests/TestProjects/Library with Spaces/Library with Spaces.csproj b/src/Simulation/Simulators.Tests/TestProjects/Library with Spaces/Library with Spaces.csproj index 89f9b7e7bf4..f8f5cffa07f 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/Library with Spaces/Library with Spaces.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/Library with Spaces/Library with Spaces.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 false @@ -12,9 +12,7 @@ - + diff --git a/src/Simulation/Simulators.Tests/TestProjects/Library1/Library1.csproj b/src/Simulation/Simulators.Tests/TestProjects/Library1/Library1.csproj index 2da5c023bb3..2714be57fcf 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/Library1/Library1.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/Library1/Library1.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Simulation/Simulators.Tests/TestProjects/Library2/Library2.csproj b/src/Simulation/Simulators.Tests/TestProjects/Library2/Library2.csproj index 2da5c023bb3..2714be57fcf 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/Library2/Library2.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/Library2/Library2.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Simulation/Simulators.Tests/TestProjects/QCIExe/QCIExe.csproj b/src/Simulation/Simulators.Tests/TestProjects/QCIExe/QCIExe.csproj index fb279f5a569..dce291568b6 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/QCIExe/QCIExe.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/QCIExe/QCIExe.csproj @@ -1,25 +1,25 @@ - - - - Library - netcoreapp3.1 - - false - false - false - true - qci.qpu - - - - - - - - - - - - - + + + + Library + netcoreapp3.1 + + false + false + false + true + qci.qpu + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Simulation/Simulators.Tests/TestProjects/QsharpExe/QsharpExe.csproj b/src/Simulation/Simulators.Tests/TestProjects/QsharpExe/QsharpExe.csproj index 85fe87c7403..6ac84ace635 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/QsharpExe/QsharpExe.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/QsharpExe/QsharpExe.csproj @@ -1,4 +1,4 @@ - + Exe diff --git a/src/Simulation/Simulators.Tests/TestProjects/TargetedExe/Program.qs b/src/Simulation/Simulators.Tests/TestProjects/TargetedExe/Program.qs new file mode 100644 index 00000000000..c08b6d4188b --- /dev/null +++ b/src/Simulation/Simulators.Tests/TestProjects/TargetedExe/Program.qs @@ -0,0 +1,16 @@ +namespace Microsoft.Quantum.Testing.Honeywell.Monomorphization { + + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Measurement; + open Microsoft.Quantum.Canon; + + @EntryPoint() + operation CallGenerics() : String { + + let arr = Default(); + using (qs = Qubit[2]) { + Ignore(Measure([PauliX, PauliX], qs)); + return "TargetedExe"; + } + } +} diff --git a/src/Simulation/Simulators.Tests/TestProjects/TargetedExe/TargetedExe.csproj b/src/Simulation/Simulators.Tests/TestProjects/TargetedExe/TargetedExe.csproj new file mode 100644 index 00000000000..f70061d4f60 --- /dev/null +++ b/src/Simulation/Simulators.Tests/TestProjects/TargetedExe/TargetedExe.csproj @@ -0,0 +1,40 @@ + + + + Exe + netcoreapp3.1 + + false + false + false + honeywell.qpu + + + + + + + + + + + + + + + + + <_ExeDir>$(MSBuildThisFileDirectory)built + + + + + + + + <_ExeFiles Include="$(OutputPath)*" /> + + + + + \ 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 cff781acc39..ee89aad55fd 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/UnitTests/UnitTests.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/UnitTests/UnitTests.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.1 diff --git a/src/Simulation/Simulators.Tests/Tests.Microsoft.Quantum.Simulators.csproj b/src/Simulation/Simulators.Tests/Tests.Microsoft.Quantum.Simulators.csproj index 4396deac881..01ba825325e 100644 --- a/src/Simulation/Simulators.Tests/Tests.Microsoft.Quantum.Simulators.csproj +++ b/src/Simulation/Simulators.Tests/Tests.Microsoft.Quantum.Simulators.csproj @@ -1,4 +1,4 @@ - + @@ -23,6 +23,9 @@ false + + false + @@ -38,12 +41,16 @@ <_ExeDir>$(MSBuildThisFileDirectory)TestProjects\QsharpExe\built\ + <_TargetedExeDir>$(MSBuildThisFileDirectory)TestProjects\TargetedExe\built\ <_ExeFiles Include="$(_ExeDir)*" /> + <_TargetedExeFiles Include="$(_TargetedExeDir)*" /> + + diff --git a/src/Simulation/Simulators/Microsoft.Quantum.Simulators.csproj b/src/Simulation/Simulators/Microsoft.Quantum.Simulators.csproj index 98541863364..794bb15909b 100644 --- a/src/Simulation/Simulators/Microsoft.Quantum.Simulators.csproj +++ b/src/Simulation/Simulators/Microsoft.Quantum.Simulators.csproj @@ -1,4 +1,4 @@ - + From 5de1e41a84a08437c914953280e0935ce0817ef1 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Thu, 13 Aug 2020 20:43:19 -0700 Subject: [PATCH 10/14] Protect simulator accessors via shared lock (#336) * Protect simulator accessors via shared lock This fixes an intermittent crash by putting shared locks around the access of the `psis` vector, where create and destroy use an exclusive lock of the same mutex Fixes #335 * Fix factory_test.hpp * Make sure returned ptr is the same one --- src/Simulation/Native/src/simulator/capi.cpp | 38 +++++++++---------- .../Native/src/simulator/factory.cpp | 27 ++++++++----- .../Native/src/simulator/factory.hpp | 3 +- .../Native/src/simulator/factory_test.cpp | 2 +- 4 files changed, 38 insertions(+), 32 deletions(-) diff --git a/src/Simulation/Native/src/simulator/capi.cpp b/src/Simulation/Native/src/simulator/capi.cpp index 5f081acb159..344445f46c4 100644 --- a/src/Simulation/Native/src/simulator/capi.cpp +++ b/src/Simulation/Native/src/simulator/capi.cpp @@ -21,13 +21,13 @@ MICROSOFT_QUANTUM_DECL void destroy(_In_ unsigned id) MICROSOFT_QUANTUM_DECL void seed(_In_ unsigned id, _In_ unsigned s) { - psis[id]->seed(s); + Microsoft::Quantum::Simulator::get(id)->seed(s); } // non-quantum MICROSOFT_QUANTUM_DECL std::size_t random_choice(_In_ unsigned id, _In_ std::size_t n, _In_reads_(n) double* p) { - return psis[id]->random(n, p); + return Microsoft::Quantum::Simulator::get(id)->random(n, p); } MICROSOFT_QUANTUM_DECL double JointEnsembleProbability(_In_ unsigned id, _In_ unsigned n, _In_reads_(n) int* b, _In_reads_(n) unsigned* q) @@ -36,35 +36,35 @@ MICROSOFT_QUANTUM_DECL double JointEnsembleProbability(_In_ unsigned id, _In_ un for (unsigned i = 0; i < n; ++i) bv.push_back(static_cast(*(b + i))); std::vector qv(q, q + n); - return psis[id]->JointEnsembleProbability( bv, qv); + return Microsoft::Quantum::Simulator::get(id)->JointEnsembleProbability( bv, qv); } MICROSOFT_QUANTUM_DECL void allocateQubit(_In_ unsigned id, _In_ unsigned q) { - psis[id]->allocateQubit(q); + Microsoft::Quantum::Simulator::get(id)->allocateQubit(q); } MICROSOFT_QUANTUM_DECL void release(_In_ unsigned id, _In_ unsigned q) { - psis[id]->release(q); + Microsoft::Quantum::Simulator::get(id)->release(q); } MICROSOFT_QUANTUM_DECL unsigned num_qubits(_In_ unsigned id) { - return psis[id]->num_qubits(); + return Microsoft::Quantum::Simulator::get(id)->num_qubits(); } #define FWDGATE1(G) \ MICROSOFT_QUANTUM_DECL void G(_In_ unsigned id, _In_ unsigned q) \ { \ - psis[id]->G(q); \ + Microsoft::Quantum::Simulator::get(id)->G(q); \ } #define FWDCSGATE1(G) \ MICROSOFT_QUANTUM_DECL void MC##G(_In_ unsigned id, _In_ unsigned n, _In_reads_(n) unsigned* c, _In_ unsigned q) \ { \ std::vector vc(c, c + n); \ - psis[id]->C##G(vc, q); \ + Microsoft::Quantum::Simulator::get(id)->C##G(vc, q); \ } #define FWD(G) FWDGATE1(G) FWDCSGATE1(G) @@ -88,14 +88,14 @@ FWD(AdjT) MICROSOFT_QUANTUM_DECL void R(_In_ unsigned id, _In_ unsigned b, _In_ double phi, _In_ unsigned q) { - psis[id]->R(static_cast(b), phi, q); + Microsoft::Quantum::Simulator::get(id)->R(static_cast(b), phi, q); } // multi-controlled rotations MICROSOFT_QUANTUM_DECL void MCR(_In_ unsigned id, _In_ unsigned b, _In_ double phi, _In_ unsigned nc, _In_reads_(nc) unsigned* c, _In_ unsigned q) { std::vector cv(c, c + nc); - psis[id]->CR(static_cast(b), phi, cv, q); + Microsoft::Quantum::Simulator::get(id)->CR(static_cast(b), phi, cv, q); } // Exponential of Pauli operators @@ -105,7 +105,7 @@ MICROSOFT_QUANTUM_DECL void Exp(_In_ unsigned id, _In_ unsigned n, _In_reads_(n) for (unsigned i = 0; i < n; ++i) bv.push_back(static_cast(*(b + i))); std::vector qv(q, q + n); - psis[id]->Exp(bv, phi, qv); + Microsoft::Quantum::Simulator::get(id)->Exp(bv, phi, qv); } MICROSOFT_QUANTUM_DECL void MCExp(_In_ unsigned id, _In_ unsigned n, _In_reads_(n) unsigned* b, _In_ double phi, _In_ unsigned nc, _In_reads_(nc) unsigned* c, _In_reads_(n) unsigned* q) { @@ -114,13 +114,13 @@ MICROSOFT_QUANTUM_DECL void MCExp(_In_ unsigned id, _In_ unsigned n, _In_reads_( bv.push_back(static_cast(*(b + i))); std::vector qv(q, q + n); std::vector cv(c, c + nc); - psis[id]->CExp(bv, phi, cv, qv); + Microsoft::Quantum::Simulator::get(id)->CExp(bv, phi, cv, qv); } // measurements MICROSOFT_QUANTUM_DECL unsigned M(_In_ unsigned id, _In_ unsigned q) { - return (unsigned)psis[id]->M(q); + return (unsigned)Microsoft::Quantum::Simulator::get(id)->M(q); } MICROSOFT_QUANTUM_DECL unsigned Measure(_In_ unsigned id, _In_ unsigned n, _In_reads_(n) unsigned* b, _In_reads_(n) unsigned* q) { @@ -128,7 +128,7 @@ MICROSOFT_QUANTUM_DECL unsigned Measure(_In_ unsigned id, _In_ unsigned n, _In_r for (unsigned i = 0; i < n; ++i) bv.push_back(static_cast(*(b + i))); std::vector qv(q, q + n); - return (unsigned)psis[id]->Measure(bv, qv); + return (unsigned)Microsoft::Quantum::Simulator::get(id)->Measure(bv, qv); } // apply permutation of basis states to the wave function @@ -136,33 +136,33 @@ MICROSOFT_QUANTUM_DECL void PermuteBasis(_In_ unsigned id, _In_ unsigned n, _In_ _In_reads_(table_size) std::size_t *permutation_table) { const std::vector qs(q, q + n); - psis[id]->permuteBasis(qs, table_size, permutation_table, false); + Microsoft::Quantum::Simulator::get(id)->permuteBasis(qs, table_size, permutation_table, false); } MICROSOFT_QUANTUM_DECL void AdjPermuteBasis(_In_ unsigned id, _In_ unsigned n, _In_reads_(n) unsigned* q, _In_ std::size_t table_size, _In_reads_(table_size) std::size_t *permutation_table) { const std::vector qs(q, q + n); - psis[id]->permuteBasis(qs, table_size, permutation_table, true); + Microsoft::Quantum::Simulator::get(id)->permuteBasis(qs, table_size, permutation_table, true); } // dump wavefunction to given callback until callback returns false MICROSOFT_QUANTUM_DECL void Dump(_In_ unsigned id, _In_ bool (*callback)(size_t, double, double)) { - psis[id]->dump(callback); + Microsoft::Quantum::Simulator::get(id)->dump(callback); } // dump the wavefunction of the subset of qubits to the given callback returns false MICROSOFT_QUANTUM_DECL bool DumpQubits(_In_ unsigned id, _In_ unsigned n, _In_reads_(n) unsigned* q, _In_ bool(*callback)(size_t, double, double)) { std::vector qs(q, q + n); - return psis[id]->dumpQubits(qs, callback); + return Microsoft::Quantum::Simulator::get(id)->dumpQubits(qs, callback); } // dump the list of logical qubit ids to given callback MICROSOFT_QUANTUM_DECL void DumpIds(_In_ unsigned id, _In_ void(*callback)(unsigned)) { - psis[id]->dumpIds(callback); + Microsoft::Quantum::Simulator::get(id)->dumpIds(callback); } } diff --git a/src/Simulation/Native/src/simulator/factory.cpp b/src/Simulation/Native/src/simulator/factory.cpp index 6d46fbcf7f7..b80b02b35f6 100644 --- a/src/Simulation/Native/src/simulator/factory.cpp +++ b/src/Simulation/Native/src/simulator/factory.cpp @@ -5,6 +5,7 @@ #include "config.hpp" #include "util/cpuid.hpp" #include +#include namespace Microsoft { @@ -31,7 +32,8 @@ namespace Microsoft { namespace Simulator { - mutex_type _mutex; + std::shared_mutex _mutex; + std::vector> _psis; SimulatorInterface* createSimulator(unsigned maxlocal) { @@ -52,26 +54,26 @@ namespace Microsoft MICROSOFT_QUANTUM_DECL unsigned create(unsigned maxlocal) { - std::lock_guard lock(_mutex); + std::lock_guard lock(_mutex); size_t emptySlot = -1; - for (auto const& s : psis) + for (auto const& s : _psis) { if (s == NULL) { - emptySlot = &s - &psis[0]; + emptySlot = &s - &_psis[0]; break; } } if (emptySlot == -1) { - psis.push_back(std::shared_ptr(createSimulator(maxlocal))); - emptySlot = psis.size() - 1; + _psis.push_back(std::shared_ptr(createSimulator(maxlocal))); + emptySlot = _psis.size() - 1; } else { - psis[emptySlot] = std::shared_ptr(createSimulator(maxlocal)); + _psis[emptySlot] = std::shared_ptr(createSimulator(maxlocal)); } return static_cast(emptySlot); @@ -79,12 +81,17 @@ namespace Microsoft MICROSOFT_QUANTUM_DECL void destroy(unsigned id) { - std::lock_guard lock(_mutex); + std::lock_guard lock(_mutex); - psis[id].reset(); + _psis[id].reset(); } - MICROSOFT_QUANTUM_DECL std::vector> psis; + MICROSOFT_QUANTUM_DECL std::shared_ptr& get(unsigned id) + { + std::shared_lock shared_lock(_mutex); + + return _psis[id]; + } } } diff --git a/src/Simulation/Native/src/simulator/factory.hpp b/src/Simulation/Native/src/simulator/factory.hpp index ec9d097fc8a..979b4a3b052 100644 --- a/src/Simulation/Native/src/simulator/factory.hpp +++ b/src/Simulation/Native/src/simulator/factory.hpp @@ -12,8 +12,7 @@ namespace Microsoft { MICROSOFT_QUANTUM_DECL unsigned create(unsigned =0u); MICROSOFT_QUANTUM_DECL void destroy(unsigned); - - extern MICROSOFT_QUANTUM_DECL std::vector> psis; + MICROSOFT_QUANTUM_DECL std::shared_ptr& get(unsigned); } } } diff --git a/src/Simulation/Native/src/simulator/factory_test.cpp b/src/Simulation/Native/src/simulator/factory_test.cpp index 6c196205713..d4745fa2d90 100644 --- a/src/Simulation/Native/src/simulator/factory_test.cpp +++ b/src/Simulation/Native/src/simulator/factory_test.cpp @@ -8,7 +8,7 @@ using namespace Microsoft::Quantum::Simulator; int main(int argc, char** argv) { - auto& sim = psis[create()]; + auto sim = get(create()); unsigned q=0; // qubit number sim->allocateQubit(q); From 898be5632bbd2d8ec87faa3ae96187c73f7ba0a9 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Fri, 14 Aug 2020 00:16:21 -0700 Subject: [PATCH 11/14] Fixing circuit in test_gates to be deterministic (#338) * Fixing circuit in test_gates to be deterministic `test_gates` in capi_test.cpp had a low but non-zero chance of measuring One instead of Zero, resulting in a test crash due to assertion failure. This rearranges the instructions to ensure the test correctly unprepares the state so that measurement is as deterministic as possible. Fixes #262 * use a more interesting circuit --- src/Simulation/Native/src/simulator/capi_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Simulation/Native/src/simulator/capi_test.cpp b/src/Simulation/Native/src/simulator/capi_test.cpp index feb725db2fa..82a2ad1b47a 100644 --- a/src/Simulation/Native/src/simulator/capi_test.cpp +++ b/src/Simulation/Native/src/simulator/capi_test.cpp @@ -115,7 +115,7 @@ void test_gates() CRx(sim_id, 1.0, 0, 1); H(sim_id, 1); - CRx(sim_id, -1.0, 0, 1); + CRz(sim_id, -1.0, 0, 1); H(sim_id, 1); assert(M(sim_id, 1)==false); From d264e26ef5d50a5f5922497b4b9da4a43fec2085 Mon Sep 17 00:00:00 2001 From: Scott Carda <55811729+ScottCarda-MS@users.noreply.github.com> Date: Fri, 14 Aug 2020 10:22:37 -0700 Subject: [PATCH 12/14] Slice Bug Fix (#330) * Replaced the nullable member access with regular member access for C# generated Slice. --- .../SimulationCodeTests.fs | 20 +++++++-------- .../CsharpGeneration/SimulationCode.fs | 2 +- .../Simulators.Tests/Circuits/Issue132.qs | 25 +++++++++++++++++++ 3 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 src/Simulation/Simulators.Tests/Circuits/Issue132.qs diff --git a/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs b/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs index 12605ed0603..3c4cb093f9f 100644 --- a/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs +++ b/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs @@ -1242,7 +1242,7 @@ namespace N1 "X.Apply(qubits.Data[0L]);" "X.Adjoint.Apply(qubits.Data[0L]);" - "X.Controlled.Apply((qubits.Data?.Slice(new QRange(1L,5L)), qubits.Data[0L]));" + "X.Controlled.Apply((qubits.Data.Slice(new QRange(1L,5L)), qubits.Data[0L]));" "call_target1.Apply((1L, X, X, X, X));" "call_target1.Apply((1L, plain.Data, adj.Data, ctr.Data, uni.Data));" @@ -1820,7 +1820,7 @@ namespace N1 "var r5 = (IQArray)QArray.Create((4L + 2L));" "var r6 = QArray.Create(r5.Length);" "var r7 = (IQArray)QArray.Add(r2, r4);" - "var r8 = (IQArray)r7?.Slice(new QRange(1L, 5L, 10L));" + "var r8 = (IQArray)r7.Slice(new QRange(1L, 5L, 10L));" "var r9 = new arrays_T1(new QArray(Pauli.PauliX, Pauli.PauliY));" "var r10 = (IQArray)QArray.Create(4L);" @@ -1828,8 +1828,8 @@ namespace N1 "var r12 = (IQArray)QArray.Create(r10.Length);" "var r13 = new arrays_T3(new QArray>(new QArray(Result.Zero, Result.One), new QArray(Result.One, Result.Zero)));" "var r14 = (IQArray)QArray.Add(qubits, register.Data);" - "var r15 = (IQArray)register.Data?.Slice(new QRange(0L, 2L));" - "var r16 = (IQArray)qubits?.Slice(new QRange(1L, -(1L)));" + "var r15 = (IQArray)register.Data.Slice(new QRange(0L, 2L));" + "var r16 = (IQArray)qubits.Slice(new QRange(1L, -(1L)));" "var r18 = (IQArray)QArray.Create(2L);" "var r19 = (IQArray)QArray.Create(7L);" "var i0 = r13.Data[0L][1L];" @@ -1860,12 +1860,12 @@ namespace N1 "var r2 = new QRange(10L,-(2L),0L);" "var ranges = (IQArray)QArray.Create(1L);" - "var s1 = (IQArray)qubits?.Slice(new QRange(0L,10L));" - "var s2 = (IQArray)qubits?.Slice(r2);" - "var s3 = (IQArray)qubits?.Slice(ranges[3L]);" - "var s4 = (IQArray)qubits?.Slice(GetMeARange.Apply(QVoid.Instance));" + "var s1 = (IQArray)qubits.Slice(new QRange(0L,10L));" + "var s2 = (IQArray)qubits.Slice(r2);" + "var s3 = (IQArray)qubits.Slice(ranges[3L]);" + "var s4 = (IQArray)qubits.Slice(GetMeARange.Apply(QVoid.Instance));" - "return qubits?.Slice(new QRange(10L,-(3L),0L));" + "return qubits.Slice(new QRange(10L,-(3L),0L));" ] |> testOneBody (applyVisitor sliceOperations) @@ -3529,7 +3529,7 @@ namespace Microsoft.Quantum.Tests.LineNumbers else { #line 20 "%%" - foreach (var c in ctrls?.Slice(new QRange(0L, 2L, r))) + foreach (var c in ctrls.Slice(new QRange(0L, 2L, r))) #line hidden { #line 21 "%%" diff --git a/src/Simulation/CsharpGeneration/SimulationCode.fs b/src/Simulation/CsharpGeneration/SimulationCode.fs index 15dfcdf5dfd..c4bd932bf03 100644 --- a/src/Simulation/CsharpGeneration/SimulationCode.fs +++ b/src/Simulation/CsharpGeneration/SimulationCode.fs @@ -561,7 +561,7 @@ module SimulationCode = and buildArrayItem a i = match i.ResolvedType.Resolution with - | Range -> ``invoke`` ((buildExpression a) <|?.|> (``ident`` "Slice")) ``(`` [ (buildExpression i) ] ``)`` + | Range -> ``invoke`` ((buildExpression a) <|.|> (``ident`` "Slice")) ``(`` [ (buildExpression i) ] ``)`` | _ -> ``item`` (buildExpression a) [ (buildExpression i) ] let buildBlock (block : QsScope) = diff --git a/src/Simulation/Simulators.Tests/Circuits/Issue132.qs b/src/Simulation/Simulators.Tests/Circuits/Issue132.qs new file mode 100644 index 00000000000..9b57996913a --- /dev/null +++ b/src/Simulation/Simulators.Tests/Circuits/Issue132.qs @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits +{ + open Microsoft.Quantum.Intrinsic; + + operation SliceGenerationTest() : Unit { + using (qs = Qubit[4]) { + PrepareCatState(qs); + if (M(qs[0]) == One) { + for (target in qs) { + X(target); + } + } + } + } + + operation PrepareCatState(register : Qubit[]) : Unit is Adj + Ctl { + H(register[0]); + for (target in register[1...]) { + CNOT(register[0], target); + } + } +} From c0b5f70e9b4f3434717a9d99467f26a56c8f89f4 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Mon, 17 Aug 2020 00:07:55 -0700 Subject: [PATCH 13/14] Fixing capi_test use of Pauli basis (#340) --- src/Simulation/Native/src/simulator/capi_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Simulation/Native/src/simulator/capi_test.cpp b/src/Simulation/Native/src/simulator/capi_test.cpp index 82a2ad1b47a..945127e260d 100644 --- a/src/Simulation/Native/src/simulator/capi_test.cpp +++ b/src/Simulation/Native/src/simulator/capi_test.cpp @@ -23,12 +23,12 @@ void CZ(unsigned sim_id, unsigned c, unsigned q) void Ry(unsigned sim_id, double phi, unsigned q) { - R(sim_id,2,phi,q); + R(sim_id,3,phi,q); } void CRz(unsigned sim_id, double phi, unsigned c, unsigned q) { - MCR(sim_id,3,phi,1,&c,q); + MCR(sim_id,2,phi,1,&c,q); } void CRx(unsigned sim_id, double phi, unsigned c, unsigned q) From ebedd2ba0597699f0f7fd2cb72000f0e2e025702 Mon Sep 17 00:00:00 2001 From: Sarah Marshall Date: Mon, 17 Aug 2020 12:51:35 -0700 Subject: [PATCH 14/14] Update Q# SDK version --- .../Microsoft.Quantum.CsharpGeneration.fsproj | 2 +- ...crosoft.Quantum.Simulation.QCTraceSimulatorRuntime.csproj | 2 +- .../QsharpCore/Microsoft.Quantum.QSharp.Core.csproj | 2 +- .../TestProjects/HoneywellExe/HoneywellExe.csproj | 2 +- .../Simulators.Tests/TestProjects/IonQExe/IonQExe.csproj | 2 +- .../Library with Spaces/Library with Spaces.csproj | 2 +- .../Simulators.Tests/TestProjects/Library1/Library1.csproj | 2 +- .../Simulators.Tests/TestProjects/Library2/Library2.csproj | 2 +- .../Simulators.Tests/TestProjects/QCIExe/QCIExe.csproj | 2 +- .../Simulators.Tests/TestProjects/QsharpExe/QsharpExe.csproj | 2 +- .../TestProjects/TargetedExe/TargetedExe.csproj | 5 +++-- .../Simulators.Tests/TestProjects/UnitTests/UnitTests.csproj | 2 +- .../Tests.Microsoft.Quantum.Simulators.csproj | 2 +- .../Simulators/Microsoft.Quantum.Simulators.csproj | 2 +- 14 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/Simulation/CsharpGeneration/Microsoft.Quantum.CsharpGeneration.fsproj b/src/Simulation/CsharpGeneration/Microsoft.Quantum.CsharpGeneration.fsproj index 5f63b02f224..adb70f031db 100644 --- a/src/Simulation/CsharpGeneration/Microsoft.Quantum.CsharpGeneration.fsproj +++ b/src/Simulation/CsharpGeneration/Microsoft.Quantum.CsharpGeneration.fsproj @@ -21,7 +21,7 @@ - + diff --git a/src/Simulation/QCTraceSimulator.Tests/Tests.Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.csproj b/src/Simulation/QCTraceSimulator.Tests/Tests.Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.csproj index 92aab6749f8..c2f1c3086fd 100644 --- a/src/Simulation/QCTraceSimulator.Tests/Tests.Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.csproj +++ b/src/Simulation/QCTraceSimulator.Tests/Tests.Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.csproj @@ -1,4 +1,4 @@ - + diff --git a/src/Simulation/QsharpCore/Microsoft.Quantum.QSharp.Core.csproj b/src/Simulation/QsharpCore/Microsoft.Quantum.QSharp.Core.csproj index ffe59c9eaec..58d1c0a798e 100644 --- a/src/Simulation/QsharpCore/Microsoft.Quantum.QSharp.Core.csproj +++ b/src/Simulation/QsharpCore/Microsoft.Quantum.QSharp.Core.csproj @@ -1,4 +1,4 @@ - + diff --git a/src/Simulation/Simulators.Tests/TestProjects/HoneywellExe/HoneywellExe.csproj b/src/Simulation/Simulators.Tests/TestProjects/HoneywellExe/HoneywellExe.csproj index a8a9bf880bc..4e889590a38 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/HoneywellExe/HoneywellExe.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/HoneywellExe/HoneywellExe.csproj @@ -1,4 +1,4 @@ - + Library diff --git a/src/Simulation/Simulators.Tests/TestProjects/IonQExe/IonQExe.csproj b/src/Simulation/Simulators.Tests/TestProjects/IonQExe/IonQExe.csproj index f1a24339112..7f122de74d7 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/IonQExe/IonQExe.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/IonQExe/IonQExe.csproj @@ -1,4 +1,4 @@ - + Library diff --git a/src/Simulation/Simulators.Tests/TestProjects/Library with Spaces/Library with Spaces.csproj b/src/Simulation/Simulators.Tests/TestProjects/Library with Spaces/Library with Spaces.csproj index 6a158dc1d65..b343833f590 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/Library with Spaces/Library with Spaces.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/Library with Spaces/Library with Spaces.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 false diff --git a/src/Simulation/Simulators.Tests/TestProjects/Library1/Library1.csproj b/src/Simulation/Simulators.Tests/TestProjects/Library1/Library1.csproj index 6bc3becc14d..a3dc73a69ff 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/Library1/Library1.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/Library1/Library1.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Simulation/Simulators.Tests/TestProjects/Library2/Library2.csproj b/src/Simulation/Simulators.Tests/TestProjects/Library2/Library2.csproj index 6bc3becc14d..a3dc73a69ff 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/Library2/Library2.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/Library2/Library2.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Simulation/Simulators.Tests/TestProjects/QCIExe/QCIExe.csproj b/src/Simulation/Simulators.Tests/TestProjects/QCIExe/QCIExe.csproj index bf5279a98b6..b822a126428 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/QCIExe/QCIExe.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/QCIExe/QCIExe.csproj @@ -1,4 +1,4 @@ - + Library diff --git a/src/Simulation/Simulators.Tests/TestProjects/QsharpExe/QsharpExe.csproj b/src/Simulation/Simulators.Tests/TestProjects/QsharpExe/QsharpExe.csproj index 6bf3908ba0c..972b97bc6c1 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/QsharpExe/QsharpExe.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/QsharpExe/QsharpExe.csproj @@ -1,4 +1,4 @@ - + Exe diff --git a/src/Simulation/Simulators.Tests/TestProjects/TargetedExe/TargetedExe.csproj b/src/Simulation/Simulators.Tests/TestProjects/TargetedExe/TargetedExe.csproj index f70061d4f60..dbd623662d8 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/TargetedExe/TargetedExe.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/TargetedExe/TargetedExe.csproj @@ -1,4 +1,4 @@ - + Exe @@ -8,6 +8,7 @@ false false honeywell.qpu + detailed @@ -37,4 +38,4 @@
- \ 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 93ba7b93252..0bcd2c473e4 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/UnitTests/UnitTests.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/UnitTests/UnitTests.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.1 diff --git a/src/Simulation/Simulators.Tests/Tests.Microsoft.Quantum.Simulators.csproj b/src/Simulation/Simulators.Tests/Tests.Microsoft.Quantum.Simulators.csproj index 941f07b9a4e..3baf54fe219 100644 --- a/src/Simulation/Simulators.Tests/Tests.Microsoft.Quantum.Simulators.csproj +++ b/src/Simulation/Simulators.Tests/Tests.Microsoft.Quantum.Simulators.csproj @@ -1,4 +1,4 @@ - + diff --git a/src/Simulation/Simulators/Microsoft.Quantum.Simulators.csproj b/src/Simulation/Simulators/Microsoft.Quantum.Simulators.csproj index 5da15f12c07..39777a7a57d 100644 --- a/src/Simulation/Simulators/Microsoft.Quantum.Simulators.csproj +++ b/src/Simulation/Simulators/Microsoft.Quantum.Simulators.csproj @@ -1,4 +1,4 @@ - +