From 79593ad019bd0c282cb18dea036bcb45946e44a3 Mon Sep 17 00:00:00 2001 From: Jonathan Daniel Date: Sun, 5 Jun 2022 11:20:54 +0300 Subject: [PATCH] Add a trace simulator in C# for custom resources estimation Count every operation and not just T in the depth --- mcx/qsharp/MultiControlX.qs | 13 ++++++- mcx/qsharp/ResourcesEstimator.cs | 64 ++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 mcx/qsharp/ResourcesEstimator.cs diff --git a/mcx/qsharp/MultiControlX.qs b/mcx/qsharp/MultiControlX.qs index 7e6ea35..99dc1b1 100644 --- a/mcx/qsharp/MultiControlX.qs +++ b/mcx/qsharp/MultiControlX.qs @@ -1,6 +1,8 @@ namespace ClassiqChallenge { open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Canon; + open Microsoft.Quantum.Convert; + open Microsoft.Quantum.Diagnostics; // Programs for the MCX gate @@ -9,8 +11,11 @@ namespace ClassiqChallenge { // Simple implementation of the Multi-Controlled X gate Controlled X(controlRegister, target); } - - @EntryPoint() + + internal function XOR(a : Bool, b : Bool) : Bool { + return (a and not b) or (b and not a); + } + operation ApplyMultiControlledX(initControl : Bool, initTarget : Bool) : Result { let controlRegisterSize = 14; @@ -30,6 +35,10 @@ namespace ClassiqChallenge { apply { MultiControlledX(controlRegister, target); } + + let expectedResult = BoolAsResult(XOR(initControl, initTarget)); + AssertQubit(expectedResult, target); + return M(target); } diff --git a/mcx/qsharp/ResourcesEstimator.cs b/mcx/qsharp/ResourcesEstimator.cs new file mode 100644 index 0000000..8db26e8 --- /dev/null +++ b/mcx/qsharp/ResourcesEstimator.cs @@ -0,0 +1,64 @@ +using System; +using System.Threading.Tasks; +using System.Collections.Generic; +using Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators; +using ClassiqChallenge; + +namespace host +{ + static class Program + { + static int DefaultPrimitiveDepth = 1; + + // See: + // https://docs.microsoft.com/en-us/dotnet/api/microsoft.quantum.simulation.simulators.qctracesimulators.qctracesimulatorconfiguration + static QCTraceSimulatorConfiguration GetConfig() + { + var config = new QCTraceSimulatorConfiguration(); + config.UseWidthCounter = true; + config.UseDepthCounter = true; + + // Optimize for using less qubits + config.OptimizeDepth = false; + + // Configure depth counting: + // Count every relevant primitive in the depth metric. + // By default only T primitives are counted, i.e. the depth is T-depth. + foreach (var primitive in new List{ + PrimitiveOperationsGroups.CNOT, + PrimitiveOperationsGroups.QubitClifford, + PrimitiveOperationsGroups.R, + PrimitiveOperationsGroups.T, + } + ) + { + config.TraceGateTimes[primitive] = DefaultPrimitiveDepth; + } + // Do not count measurements - they are only helpers in this case. + config.TraceGateTimes[PrimitiveOperationsGroups.Measure] = 0; + + foreach (var kvp in config.TraceGateTimes) + { + Console.WriteLine(kvp); + } + return config; + } + + // See: + // https://docs.microsoft.com/en-us/azure/quantum/machines/qc-trace-simulator/width-counter + static async Task Main(string[] args) + { + var sim = new QCTraceSimulator(GetConfig()); + + var singleQubitResult = await ApplyMultiControlledX.Run( + sim, initControl: false, initTarget: false + ); + + double width = sim.GetMetric(MetricsNames.WidthCounter.ExtraWidth); + double depth = sim.GetMetric(MetricsNames.DepthCounter.Depth); + + Console.WriteLine($"Single qubit result: {singleQubitResult}"); + Console.WriteLine($"Width: {width}, Depth: {depth}."); + } + } +}