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

Commit

Permalink
Sparse simulator (core components) (#939)
Browse files Browse the repository at this point in the history
Co-authored-by: DmitryVasilevsky <60718360+DmitryVasilevsky@users.noreply.github.com>
Co-authored-by: Sam Jaques <sam.e.jaques@gmail.com>
Co-authored-by: Dmitry Vasilevsky <dmitryv@microsoft.com>
Co-authored-by: Thomas Haener <thomashaener@users.noreply.github.com>
Co-authored-by: Robin Kuzmin <9372582+kuzminrobin@users.noreply.github.com>
Co-authored-by: Thomas Haener <thhaner@microsoft.com>
Co-authored-by: Robin Kuzmin <kuzmin.robin@gmail.com>
Co-authored-by: Bettina Heim <beheim@microsoft.com>
  • Loading branch information
9 people authored Feb 17, 2022
1 parent 2e9962e commit e5be79b
Show file tree
Hide file tree
Showing 82 changed files with 7,421 additions and 886 deletions.
9 changes: 6 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ ClientBin/
*.publishsettings
orleans.codegen.cs

# Including strong name files can present a security risk
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk

Expand Down Expand Up @@ -328,7 +328,7 @@ __pycache__/
# OpenCover UI analysis results
OpenCover/

# Azure Stream Analytics local run output
# Azure Stream Analytics local run output
ASALocalRun/

# MSBuild Binary and Structured Log
Expand All @@ -337,7 +337,7 @@ ASALocalRun/
# NVidia Nsight GPU debugger configuration file
*.nvuser

# MFractors (Xamarin productivity tool) working folder
# MFractors (Xamarin productivity tool) working folder
.mfractor/

/src/Simulation/Simulators.Tests/TestProjects/QSharpExe/built
Expand All @@ -357,6 +357,9 @@ xplat
src/Simulation/Native/win10/Microsoft.Quantum.Simulator.Runtime.dll
src/Simulation/Native/linux/libMicrosoft.Quantum.Simulator.Runtime.so
src/Simulation/Native/osx/libMicrosoft.Quantum.Simulator.Runtime.dylib
src/Simulation/Native/win10/SparseQuantumSimulator.dll
src/Simulation/Native/linux/libSparseQuantumSimulator.so
src/Simulation/Native/osx/libSparseQuantumSimulator.dylib
src/Simulation/Native/win10/Microsoft.Quantum.Experimental.Simulators.Runtime.dll
src/Simulation/Native/linux/Microsoft.Quantum.Experimental.Simulators.Runtime.dll
src/Simulation/Native/osx/Microsoft.Quantum.Experimental.Simulators.Runtime.dll
2 changes: 1 addition & 1 deletion Simulation.sln
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,7 @@ Global
{EB6E3DBD-C884-4241-9BC4-8281191D1F53} = {34D419E9-CCF1-4E48-9FA4-3AD4B86BEEB4}
{E1A463D7-2E23-4134-BE04-1EFF7A546813} = {93409CC3-8DF9-45FA-AE21-16A19FDEF650}
{789C86D9-CE77-40DA-BDDD-979436952512} = {93409CC3-8DF9-45FA-AE21-16A19FDEF650}
{7E24885B-D86D-477E-A840-06FA53C33FE1} = {34D419E9-CCF1-4E48-9FA4-3AD4B86BEEB4}
{7E24885B-D86D-477E-A840-06FA53C33FE1} = {93409CC3-8DF9-45FA-AE21-16A19FDEF650}
{7F80466B-A6B5-4EF1-A9E9-22ABAE3C20C1} = {34D419E9-CCF1-4E48-9FA4-3AD4B86BEEB4}
{7F7BB60A-5DCB-469E-8546-1BE9E3CAC833} = {F6C2D4C0-12DC-40E3-9C86-FA5308D9B567}
{EAC5EAE7-D1B3-4726-AFDB-73000E62176A} = {7F7BB60A-5DCB-469E-8546-1BE9E3CAC833}
Expand Down
6 changes: 5 additions & 1 deletion bootstrap.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,15 @@ Pop-Location

if (-not (Test-Path Env:/AGENT_OS)) { # If not CI build, i.e. local build (if AGENT_OS envvar is not defined)
if ($Env:ENABLE_NATIVE -ne "false") {
Write-Host "Build release flavor of the native simulator"
$Env:BUILD_CONFIGURATION = "Release"
Write-Host "Build release flavor of the full state simulator"
Push-Location (Join-Path $PSScriptRoot "src/Simulation/Native")
.\build-native-simulator.ps1
Pop-Location

Write-Host "Build release flavor of the Sparse Simulator"
Invoke-Expression (Join-Path $PSScriptRoot "src" "Simulation" "NativeSparseSimulator" "build.ps1")

Push-Location (Join-Path $PSScriptRoot "src/Simulation/qdk_sim_rs")
# Don't run the experimental simulator build if we're local
# and prerequisites are missing.
Expand Down
2 changes: 2 additions & 0 deletions build/build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ if ($Env:ENABLE_NATIVE -ne "false") {
if ($LastExitCode -ne 0) {
$script:all_ok = $False
}

( & (Join-Path $PSScriptRoot .. src Simulation NativeSparseSimulator build.ps1) ) || ( $script:all_ok = $False )
} else {
Write-Host "Skipping build of native simulator because ENABLE_NATIVE variable is set to: $Env:ENABLE_NATIVE."
}
Expand Down
15 changes: 13 additions & 2 deletions build/pack.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ Push-Location (Join-Path $PSScriptRoot ../src/Simulation/Native)
Copy-Item -Verbose "$DROP/Microsoft.Quantum.Simulator.Runtime.dll" "win10/Microsoft.Quantum.Simulator.Runtime.dll"
}

$DROP = "$Env:DROP_NATIVE/src/Simulation/NativeSparseSimulator/build"
Write-Host "##[info]Copying NativeSparseSimulator files from $DROP...";
If (Test-Path "$DROP/libSparseQuantumSimulator.dylib") {
Copy-Item -Verbose "$DROP/libSparseQuantumSimulator.dylib" "osx/libSparseQuantumSimulator.dylib"
}
If (Test-Path "$DROP/libSparseQuantumSimulator.so") {
Copy-Item -Verbose "$DROP/libSparseQuantumSimulator.so" "linux/libSparseQuantumSimulator.so"
}
If (Test-Path "$DROP/SparseQuantumSimulator.dll") {
Copy-Item -Verbose "$DROP/SparseQuantumSimulator.dll" "win10/SparseQuantumSimulator.dll"
}

$DROP = "$Env:DROP_NATIVE/src/Simulation/qdk_sim_rs/drop";
Write-Host "##[info]Copying qdk_sim_rs files from $DROP...";
Expand All @@ -43,7 +54,7 @@ Pop-Location

function Pack-One() {
Param(
$project,
$project,
$option1 = "",
$option2 = "",
$option3 = "",
Expand Down Expand Up @@ -74,7 +85,7 @@ function Pack-One() {

function Pack-Dotnet() {
Param(
$project,
$project,
$option1 = "",
$option2 = "",
$option3 = "",
Expand Down
2 changes: 2 additions & 0 deletions build/test.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
$all_ok = $True

if ($Env:ENABLE_NATIVE -ne "false") {
( & (Join-Path $PSScriptRoot .. src Simulation NativeSparseSimulator test.ps1 ) ) || ( $script:all_ok = $False )

$nativeSimulator = (Join-Path $PSScriptRoot "../src/Simulation/Native")
& "$nativeSimulator/test-native-simulator.ps1"
if ($LastExitCode -ne 0) {
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"msbuild-sdks": {
"Microsoft.Quantum.Sdk": "0.22.192799-alpha"
"Microsoft.Quantum.Sdk": "0.22.192949-beta"
}
}
4 changes: 2 additions & 2 deletions src/Qir/Runtime/lib/Simulators/FullstateSimulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,11 @@ namespace Quantum
{
std::cout << "*********************" << std::endl;
this->GetState(
[](size_t idx, double re, double im)
[](const char* idx, double re, double im)
{
if (!Close(re, 0.0) || !Close(im, 0.0))
{
std::cout << "|" << std::bitset<8>(idx) << ">: " << re << "+" << im << "i" << std::endl;
std::cout << "|" << idx << ">: " << re << "+" << im << "i" << std::endl;
}
return true;
});
Expand Down
3 changes: 2 additions & 1 deletion src/Qir/Runtime/public/QSharpSimApi_I.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ namespace Quantum

// The callback should be invoked on each basis vector (in the standard computational basis) in little-endian
// order until it returns `false` or the state is fully dumped.
typedef bool (*TGetStateCallback)(size_t /*basis vector*/, double /* amplitude Re*/, double /* amplitude Im*/);
typedef bool (*TGetStateCallback)(const char* /*basis vector*/, double /* amplitude Re*/,
double /* amplitude Im*/);

// Deprecated, use `DumpMachine()` and `DumpRegister()` instead.
virtual void GetState(TGetStateCallback callback) = 0;
Expand Down
15 changes: 13 additions & 2 deletions src/Qir/Tests/FullstateSimulator/FullstateSimulatorTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <complex>
#include <memory>
#include <string>
#include <vector>

#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
Expand Down Expand Up @@ -347,9 +348,14 @@ TEST_CASE("Fullstate simulator: get qubit state of Bell state", "[fullstate_simu
// 1/sqrt(2)(|00> + |11>)x|0>

dynamic_cast<IDiagnostics*>(sim.get())->GetState(
[](size_t idx, double re, double im)
[](const char* idxStr, double re, double im)
{
norm += re * re + im * im;
size_t idx = 0;
for (size_t i = 0; idxStr[i] != '\0'; ++i)
{
idx |= (idxStr[i] == '1' ? 1u : 0u) << i;
}
REQUIRE(idx < 4);
switch (idx)
{
Expand All @@ -372,9 +378,14 @@ TEST_CASE("Fullstate simulator: get qubit state of Bell state", "[fullstate_simu
// 1/sqrt(2)(|00> + |11>)xi|1>

dynamic_cast<IDiagnostics*>(sim.get())->GetState(
[](size_t idx, double re, double im)
[](const char* idxStr, double re, double im)
{
norm += re * re + im * im;
size_t idx = 0;
for (size_t i = 0; idxStr[i] != '\0'; ++i)
{
idx |= (idxStr[i] == '1' ? 1u : 0u) << i;
}
switch (idx)
{
case 4:
Expand Down
2 changes: 1 addition & 1 deletion src/Qir/Tools/Microsoft.Quantum.Qir.Runtime.Tools.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
<PackageReference Include="Microsoft.Quantum.QirGeneration" Version="0.22.192799-alpha" />
<PackageReference Include="Microsoft.Quantum.QirGeneration" Version="0.22.192949-beta" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Quantum.Compiler" Version="0.22.192799-alpha" />
<PackageReference Include="Microsoft.Quantum.Compiler" Version="0.22.192949-beta" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.6.0" />
</ItemGroup>

Expand Down
6 changes: 6 additions & 0 deletions src/Simulation/Common/Simulators.Dev.props
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<NativeRootPath>$([MSBuild]::NormalizePath($(EnlistmentRoot)src/Simulation/Native))</NativeRootPath>
<NativeBuildPath>$([MSBuild]::NormalizePath($(NativeRootPath)/build/drop))</NativeBuildPath>
<ExperimentalSimBuildPath>$([MSBuild]::NormalizePath($(EnlistmentRoot)src/Simulation/qdk_sim_rs/drop))</ExperimentalSimBuildPath>
<NativeSparseSimBuildPath>$([MSBuild]::NormalizePath($(EnlistmentRoot)src/Simulation/NativeSparseSimulator/build))</NativeSparseSimBuildPath>
</PropertyGroup>

<ItemGroup>
Expand All @@ -26,6 +27,11 @@
<NativeDll Include="$([MSBuild]::NormalizePath($(ExperimentalSimBuildPath)/libqdk_sim.dylib))" Dest="osx/Microsoft.Quantum.Experimental.Simulators.Runtime.dll" />
<NativeDll Include="$([MSBuild]::NormalizePath($(ExperimentalSimBuildPath)/libqdk_sim.so))" Dest="linux/Microsoft.Quantum.Experimental.Simulators.Runtime.dll" />
<NativeDll Include="$([MSBuild]::NormalizePath($(ExperimentalSimBuildPath)/qdk_sim.dll))" Dest="win10/Microsoft.Quantum.Experimental.Simulators.Runtime.dll" />

<!-- Native Sparse Simulator: -->
<NativeDll Include="$([MSBuild]::NormalizePath($(NativeSparseSimBuildPath)/libSparseQuantumSimulator.dylib))" Dest="osx/libSparseQuantumSimulator.dylib" />
<NativeDll Include="$([MSBuild]::NormalizePath($(NativeSparseSimBuildPath)/libSparseQuantumSimulator.so))" Dest="linux/libSparseQuantumSimulator.so" />
<NativeDll Include="$([MSBuild]::NormalizePath($(NativeSparseSimBuildPath)/SparseQuantumSimulator.dll))" Dest="win10/SparseQuantumSimulator.dll" />
</ItemGroup>

<Copy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="Microsoft.Quantum.CSharpGeneration" Version="0.22.192799-alpha" />
<PackageReference Include="Microsoft.Quantum.CSharpGeneration" Version="0.22.192949-beta" />
</ItemGroup>

<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions src/Simulation/EntryPointDriver/Driver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ public Driver(DriverSettings settings, IReadOnlyCollection<IEntryPoint> entryPoi
suggestions: new[]
{
this.settings.QuantumSimulatorName,
// this.settings.SparseSimulatorName, // uncomment to enable listing the sparse simulator in the command line help
this.settings.ToffoliSimulatorName,
this.settings.ResourcesEstimatorName,
this.settings.DefaultSimulatorName
Expand Down
8 changes: 8 additions & 0 deletions src/Simulation/EntryPointDriver/DriverSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ public sealed class DriverSettings
/// </summary>
internal string QuantumSimulatorName { get; }

/// <summary>
/// The name of the sparse simulator.
/// </summary>
internal string SparseSimulatorName { get; }

/// <summary>
/// The name of the Toffoli simulator.
/// </summary>
Expand Down Expand Up @@ -53,6 +58,7 @@ public sealed class DriverSettings
/// </summary>
/// <param name="simulatorOptionAliases">The aliases for the simulator command-line option.</param>
/// <param name="quantumSimulatorName">The name of the quantum simulator.</param>
/// <param name="sparseSimulatorName">The name of the sparse simulator.</param>
/// <param name="toffoliSimulatorName">The name of the Toffoli simulator.</param>
/// <param name="resourcesEstimatorName">The name of the resources estimator.</param>
/// <param name="defaultSimulatorName">The name of the default simulator to use.</param>
Expand All @@ -61,6 +67,7 @@ public sealed class DriverSettings
public DriverSettings(
ImmutableList<string> simulatorOptionAliases,
string quantumSimulatorName,
string sparseSimulatorName,
string toffoliSimulatorName,
string resourcesEstimatorName,
string defaultSimulatorName,
Expand All @@ -69,6 +76,7 @@ public DriverSettings(
{
SimulatorOptionAliases = simulatorOptionAliases;
QuantumSimulatorName = quantumSimulatorName;
SparseSimulatorName = sparseSimulatorName;
ToffoliSimulatorName = toffoliSimulatorName;
ResourcesEstimatorName = resourcesEstimatorName;
DefaultSimulatorName = defaultSimulatorName;
Expand Down
2 changes: 2 additions & 0 deletions src/Simulation/EntryPointDriver/Simulation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public static async Task<int> Simulate(
var (isCustom, createSimulator) =
simulator == settings.QuantumSimulatorName
? (false, () => new QuantumSimulator())
: simulator == settings.SparseSimulatorName
? (false, () => new SparseSimulator())
: simulator == settings.ToffoliSimulatorName
? (false, new Func<IOperationFactory>(() => new ToffoliSimulator()))
: (true, settings.CreateDefaultCustomSimulator);
Expand Down
4 changes: 2 additions & 2 deletions src/Simulation/Native/src/simulator/capi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ extern "C"
}

// dump wavefunction to given callback until callback returns false
MICROSOFT_QUANTUM_DECL void Dump(_In_ unsigned id, _In_ bool (*callback)(size_t, double, double))
MICROSOFT_QUANTUM_DECL void Dump(_In_ unsigned id, _In_ bool (*callback)(const char*, double, double))
{
Microsoft::Quantum::Simulator::get(id)->dump(callback);
}
Expand All @@ -217,7 +217,7 @@ extern "C"
_In_ unsigned id,
_In_ unsigned n,
_In_reads_(n) unsigned* q,
_In_ bool (*callback)(size_t, double, double))
_In_ bool (*callback)(const char*, double, double))
{
std::vector<unsigned> qs(q, q + n);
return Microsoft::Quantum::Simulator::get(id)->dumpQubits(qs, callback);
Expand Down
4 changes: 2 additions & 2 deletions src/Simulation/Native/src/simulator/capi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ extern "C"
MICROSOFT_QUANTUM_DECL unsigned init(); // NOLINT
MICROSOFT_QUANTUM_DECL void destroy(_In_ unsigned sid); // NOLINT
MICROSOFT_QUANTUM_DECL void seed(_In_ unsigned sid, _In_ unsigned s); // NOLINT
MICROSOFT_QUANTUM_DECL void Dump(_In_ unsigned sid, _In_ bool (*callback)(size_t, double, double));
MICROSOFT_QUANTUM_DECL void Dump(_In_ unsigned sid, _In_ bool (*callback)(const char*, double, double));
MICROSOFT_QUANTUM_DECL bool DumpQubits(
_In_ unsigned sid,
_In_ unsigned n,
_In_reads_(n) unsigned* q,
_In_ bool (*callback)(size_t, double, double));
_In_ bool (*callback)(const char*, double, double));

typedef void* TDumpLocation;
typedef bool (*TDumpToLocationCallback)(size_t, double, double, TDumpLocation);
Expand Down
2 changes: 1 addition & 1 deletion src/Simulation/Native/src/simulator/capi_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void CRx(unsigned sim_id, double phi, unsigned c, unsigned q)

void dump(unsigned sim_id, const char* label)
{
auto dump_callback = [](size_t idx, double r, double i) {
auto dump_callback = [](const char* idx, double r, double i) {
std::cout << idx << ":\t" << r << '\t' << i << '\n';
return true;
};
Expand Down
2 changes: 1 addition & 1 deletion src/Simulation/Native/src/simulator/dbw_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ void CRx(unsigned sim_id, double phi, unsigned c, unsigned q)

void dump(unsigned sim_id, const char* label)
{
auto dump_callback = [](size_t idx, double r, double i) {
auto dump_callback = [](char const* idx, double r, double i) {
std::cout << idx << ":\t" << r << '\t' << i << '\n';
return true;
};
Expand Down
17 changes: 12 additions & 5 deletions src/Simulation/Native/src/simulator/simulator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,15 +290,19 @@ class Simulator : public Microsoft::Quantum::Simulator::SimulatorInterface
return psi.data().data();
}

void dump(bool (*callback)(size_t, double, double))
void dump(bool (*callback)(const char*, double, double))
{
recursive_lock_type l(getmutex());
flush();

auto wfn = psi.data();
auto nq = num_qubits();
std::string label_str(nq, '0');
for (std::size_t i = 0; i < wfn.size(); i++)
{
if (!callback(i, wfn[i].real(), wfn[i].imag())) return;
for (std::size_t j = 0; j < nq; ++j)
label_str[j] = ((i >> j)&1) ? '1' : '0';
if (!callback(label_str.c_str(), wfn[i].real(), wfn[i].imag())) return;
}
}

Expand Down Expand Up @@ -345,17 +349,20 @@ class Simulator : public Microsoft::Quantum::Simulator::SimulatorInterface
}
}

bool dumpQubits(std::vector<logical_qubit_id> const& qs, bool (*callback)(size_t, double, double))
bool dumpQubits(std::vector<logical_qubit_id> const& qs, bool (*callback)(const char*, double, double))
{
assert(qs.size() <= num_qubits());

WavefunctionStorage wfn(1ull << qs.size());

auto nq = num_qubits();
std::string label_str(nq, '0');
if (subsytemwavefunction(qs, wfn, 1e-10))
{
for (std::size_t i = 0; i < wfn.size(); i++)
{
if (!callback(i, wfn[i].real(), wfn[i].imag())) break;
for (std::size_t j = 0; j < nq; ++j)
label_str[j] = ((i >> j)&1) ? '1' : '0';
if (!callback(label_str.c_str(), wfn[i].real(), wfn[i].imag())) break;
}
return true;
}
Expand Down
Loading

0 comments on commit e5be79b

Please sign in to comment.