diff --git a/mcx/qsharp/ResourcesEstimator.cs b/mcx/qsharp/ResourcesEstimator.cs index 8db26e8..4ce8232 100644 --- a/mcx/qsharp/ResourcesEstimator.cs +++ b/mcx/qsharp/ResourcesEstimator.cs @@ -2,7 +2,7 @@ using System.Threading.Tasks; using System.Collections.Generic; using Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators; -using ClassiqChallenge; +using TestTraceSimulator; namespace host { @@ -12,31 +12,28 @@ static class Program // See: // https://docs.microsoft.com/en-us/dotnet/api/microsoft.quantum.simulation.simulators.qctracesimulators.qctracesimulatorconfiguration - static QCTraceSimulatorConfiguration GetConfig() + static QCTraceSimulatorConfiguration GetConfig(bool tDepth = false) { var config = new QCTraceSimulatorConfiguration(); config.UseWidthCounter = true; config.UseDepthCounter = true; - // Optimize for using less qubits - config.OptimizeDepth = false; + // Optimize for minimal depth + config.OptimizeDepth = true; // 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, - } - ) + if (!tDepth) { - config.TraceGateTimes[primitive] = DefaultPrimitiveDepth; + foreach (var primitive in Enum.GetNames()) + { + config.TraceGateTimes[Enum.Parse(primitive)] = + DefaultPrimitiveDepth; + } } - // Do not count measurements - they are only helpers in this case. - config.TraceGateTimes[PrimitiveOperationsGroups.Measure] = 0; + Console.WriteLine("Primitives depth:"); foreach (var kvp in config.TraceGateTimes) { Console.WriteLine(kvp); @@ -48,17 +45,29 @@ static QCTraceSimulatorConfiguration GetConfig() // 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 tDepth = false; - var singleQubitResult = await ApplyMultiControlledX.Run( - sim, initControl: false, initTarget: false - ); + if (args.Length > 0) + { + tDepth = args[0] == "--t-depth"; + } - double width = sim.GetMetric(MetricsNames.WidthCounter.ExtraWidth); - double depth = sim.GetMetric(MetricsNames.DepthCounter.Depth); + var config = GetConfig(tDepth: tDepth); + var simOriginal = new QCTraceSimulator(config); + var simNonOriginal = new QCTraceSimulator(config); - Console.WriteLine($"Single qubit result: {singleQubitResult}"); - Console.WriteLine($"Width: {width}, Depth: {depth}."); + await Task.WhenAll( + TestCCNOT.Run(simOriginal, original: true), + TestCCNOT.Run(simNonOriginal, original: false) + ); + + foreach (var sim in new List { simOriginal, simNonOriginal }) + { + double depth = sim.GetMetric(MetricsNames.DepthCounter.Depth); + double width = sim.GetMetric(MetricsNames.WidthCounter.ExtraWidth); + Console.WriteLine(sim.Name); + Console.WriteLine($"Depth: {depth}, width: {width}."); + } } } } diff --git a/mcx/qsharp/TestCCNOT.qs b/mcx/qsharp/TestCCNOT.qs new file mode 100644 index 0000000..746b749 --- /dev/null +++ b/mcx/qsharp/TestCCNOT.qs @@ -0,0 +1,39 @@ +namespace TestTraceSimulator { + open Microsoft.Quantum.Intrinsic; + + // See: + // https://github.com/microsoft/qsharp-runtime/blob/1761b379397520c0fa10ec8d2592f1df2b1acecf/src/Simulation/TargetDefinitions/Decompositions/CCNOTFromCCZ.qs#L22-L31 + operation CCNOTFromCCZ(control1 : Qubit, control2 : Qubit, target : Qubit) : Unit { + within { + H(target); + } + // The internal `CCZ` operation: + // https://github.com/microsoft/qsharp-runtime/blob/1761b379397520c0fa10ec8d2592f1df2b1acecf/src/Simulation/TargetDefinitions/Decompositions/Utils.qs#L101-L116 + apply { + Adjoint T(control1); + Adjoint T(control2); + CNOT(target, control1); + T(control1); + CNOT(control2, target); + CNOT(control2, control1); + T(target); + Adjoint T(control1); + CNOT(control2, target); + CNOT(target, control1); + Adjoint T(target); + T(control1); + CNOT(control2, control1); + } + } + + operation TestCCNOT(original : Bool) : Unit { + use (control1, control2, target) = (Qubit(), Qubit(), Qubit()); + if original { + CCNOT(control1, control2, target); + } + else { + CCNOTFromCCZ(control1, control2, target); + } + } + +}