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

Commit

Permalink
Add new files
Browse files Browse the repository at this point in the history
  • Loading branch information
adithyabsk committed Aug 19, 2021
1 parent 487c143 commit 3aa4661
Show file tree
Hide file tree
Showing 3 changed files with 241 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#nullable enable

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.Quantum.Simulation.Core;
using Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime;
using Microsoft.Quantum.Simulation.Simulators;
using Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators;

namespace Simulator
{
public class ResourcesEstimatorWithAdditionalPrimitiveOperations : ResourcesEstimator
{
public ResourcesEstimatorWithAdditionalPrimitiveOperations() : this(ResourcesEstimator.RecommendedConfig())
{
}

public ResourcesEstimatorWithAdditionalPrimitiveOperations(QCTraceSimulatorConfiguration config) : base(WithoutPrimitiveOperationsCounter(config))
{
}

private static QCTraceSimulatorConfiguration WithoutPrimitiveOperationsCounter(QCTraceSimulatorConfiguration config)
{
config.UsePrimitiveOperationsCounter = false;
return config;
}

protected virtual IDictionary<string, IEnumerable<Type>>? AdditionalOperations { get; }

protected override void InitializeQCTracerCoreListeners(IList<IQCTraceSimulatorListener> listeners)
{
base.InitializeQCTracerCoreListeners(listeners);

// add custom primitive operations listener
var primitiveOperationsIdToNames = new Dictionary<int, string>();
Utils.FillDictionaryForEnumNames<PrimitiveOperationsGroups, int>(primitiveOperationsIdToNames);

var operationNameToId = new Dictionary<string, int>();

if (AdditionalOperations != null)
{
foreach (var name in AdditionalOperations.Keys)
{
var id = primitiveOperationsIdToNames.Count;
operationNameToId[name] = id;
primitiveOperationsIdToNames.Add(id, name);
}
}

var cfg = new PrimitiveOperationsCounterConfiguration { primitiveOperationsNames = primitiveOperationsIdToNames.Values.ToArray() };
var operationsCounter = new PrimitiveOperationsCounter(cfg);
tCoreConfig.Listeners.Add(operationsCounter);

if (AdditionalOperations != null)
{
var compare = new AssignableTypeComparer();
this.OnOperationStart += (callable, data) => {
var unwrapped = callable.UnwrapCallable();
foreach (var (name, types) in AdditionalOperations)
{
if (types.Contains(unwrapped.GetType(), compare))
{
var adjName = $"Adjoint{name}";
var key = (callable.Variant == OperationFunctor.Adjoint || callable.Variant == OperationFunctor.ControlledAdjoint) && AdditionalOperations.ContainsKey(adjName)
? adjName
: name;
operationsCounter.OnPrimitiveOperation(operationNameToId[key], new object[] { }, 0.0);
break;
}
}
};
}
}

private class AssignableTypeComparer : IEqualityComparer<Type>
{
public bool Equals([AllowNull] Type x, [AllowNull] Type y)
{
return x != null && x.IsAssignableFrom(y);
}

public int GetHashCode([DisallowNull] Type obj)
{
return obj.GetHashCode();
}
}
}
}
62 changes: 62 additions & 0 deletions src/Simulation/Simulators/ResourcesEstimator/RuntimeCounter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#nullable enable

using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.Quantum.Simulation.Core;
using Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime;

namespace Simulator
{
public class RuntimeCounter : IQCTraceSimulatorListener, ICallGraphStatistics
{
public RuntimeCounter()
{
AddToCallStack(CallGraphEdge.CallGraphRootHashed, OperationFunctor.Body);
stats = new StatisticsCollector<CallGraphEdge>(
new [] { "Runtime" },
StatisticsCollector<CallGraphEdge>.DefaultStatistics()
);
}

public bool NeedsTracingDataInQubits => false;

public object? NewTracingData(long qubitId) => null;

public void OnAllocate(object[] qubitsTraceData) {}

public void OnRelease(object[] qubitsTraceData) {}

public void OnBorrow(object[] qubitsTraceData, long newQubitsAllocated) {}

public void OnReturn(object[] qubitsTraceData, long qubitReleased) {}

public void OnOperationStart(HashedString name, OperationFunctor variant, object[] qubitsTraceData)
{
AddToCallStack(name, variant);
operationCallStack.Peek().Watch.Start();
}

public void OnOperationEnd(object[] returnedQubitsTraceData)
{
var record = operationCallStack.Pop();
record.Watch.Stop();
Debug.Assert(operationCallStack.Count != 0, "Operation call stack must never get empty");
stats.AddSample(new CallGraphEdge(record.OperationName, operationCallStack.Peek().OperationName, record.FunctorSpecialization, operationCallStack.Peek().FunctorSpecialization), new [] { (double)record.Watch.ElapsedMilliseconds });
}

public void OnPrimitiveOperation(int id, object[] qubitsTraceData, double primitiveOperationDuration) {}

public IStatisticCollectorResults<CallGraphEdge> Results { get => stats as IStatisticCollectorResults<CallGraphEdge>; }

private record OperationCallRecord(HashedString OperationName, OperationFunctor FunctorSpecialization)
{
public Stopwatch Watch { get; } = new();
}

private readonly Stack<OperationCallRecord> operationCallStack = new Stack<OperationCallRecord>();
private readonly StatisticsCollector<CallGraphEdge> stats;

private void AddToCallStack(HashedString operationName, OperationFunctor functorSpecialization) =>
operationCallStack.Push(new OperationCallRecord(operationName, functorSpecialization));
}
}
87 changes: 87 additions & 0 deletions src/Simulation/Simulators/ResourcesEstimator/Simulator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Data;
using Microsoft.Quantum.Simulation.Simulators;
using Microsoft.Quantum.Simulation.Core;
using Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime;
using Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators;

// using System.IO;
// using System.Threading.Tasks;

namespace Simulator
{
public class AdvancedSimulator : ResourcesEstimatorWithAdditionalPrimitiveOperations
{
// public override Task<O> Run<T, I, O>(I args)
// {
// var result = base.Run<T, I, O>(args).Result;
// var name = typeof(T).Name;
// File.WriteAllText($"{name}.txt", ToTSV());
// return Task.Run(() => result);
// }

protected override IDictionary<string, IEnumerable<Type>> AdditionalOperations { get; } =
new Dictionary<string, IEnumerable<Type>> {
["CCZ"] = new [] { typeof(Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators.Circuits.CCZ) },
["And"] = new [] { typeof(Microsoft.Quantum.Canon.ApplyAnd), typeof(Microsoft.Quantum.Canon.ApplyLowDepthAnd) },
["AdjointAnd"] = Array.Empty<Type>()
};

protected override void InitializeQCTracerCoreListeners(IList<IQCTraceSimulatorListener> listeners)
{
base.InitializeQCTracerCoreListeners(listeners);
tCoreConfig.Listeners.Add(new RuntimeCounter());
}

// CCNOT(a, b, c);
// T(a);
// T(b);

// Original QDK ResEst. -> 9 Ts
// New QDK ResEst. -> 1 CCZ, 2 Ts

public override DataTable Data
{
get
{
var data = base.Data;

var androw = data.Rows.Find("And");
var adjandrow = data.Rows.Find("AdjointAnd");
var cczrow = data.Rows.Find("CCZ");
var trow = data.Rows.Find("T");

// Update T count
trow["Sum"] = (double)trow["Sum"] - 4 * (double)androw["Sum"] - 7 * (double)cczrow["Sum"];
trow["Max"] = (double)trow["Max"] - 4 * (double)androw["Max"] - 7 * (double)cczrow["Max"];

// TODO: update CNOT, QubitClifford, and Measure as well

return data;
}
}

#region Direct access to counts
public long CNOT => (long)(double)Data!.Rows!.Find("CNOT")![1];
public long QubitClifford => (long)(double)Data!.Rows!.Find("QubitClifford")![1];
public long T => (long)(double)Data!.Rows!.Find("T")![1];
public long Measure => (long)(double)Data!.Rows!.Find("Measure")![1];
public long QubitCount => (long)(double)Data!.Rows!.Find("QubitCount")![1];
public long Depth => (long)(double)Data!.Rows!.Find("Depth")![1];
public long CCZ => (long)(double)Data!.Rows!.Find("CCZ")![1];
public long And => (long)(double)Data!.Rows!.Find("And")![1];
public long AdjointAnd => (long)(double)Data!.Rows!.Find("AdjointAnd")![1];
#endregion

public override O Execute<T, I, O>(I args)
{
var result = base.Execute<T, I, O>(args);
Console.WriteLine("");
Console.WriteLine("---BEGIN TABLE---");
Console.WriteLine(ToTSV());
Console.WriteLine("---END TABLE---");
return result;
}
}
}

0 comments on commit 3aa4661

Please sign in to comment.