-
Notifications
You must be signed in to change notification settings - Fork 90
Add more metrics to resource estimator #801
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The logic in this class should be merged directly with the code in the |
||
{ | ||
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; } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was intentionally made a property to be generic for arbitrary additional operations. I think it's okay to hard code the additional operators and not providing this property when merging it with the |
||
|
||
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(); | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#nullable enable | ||
adithyabsk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using Microsoft.Quantum.Simulation.Core; | ||
using Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime; | ||
|
||
namespace Simulator | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The namespace should be |
||
{ | ||
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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no documentation in this file. At least the non-empty methods should contain some information on what they are implementing. |
||
{ | ||
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)); | ||
} | ||
} |
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 | ||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This class and its logic should be merged with the existing |
||||||||||||||||||||
{ | ||||||||||||||||||||
// 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); | ||||||||||||||||||||
// } | ||||||||||||||||||||
Comment on lines
+16
to
+22
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||
|
||||||||||||||||||||
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 | ||||||||||||||||||||
Comment on lines
+37
to
+42
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment should contain some context of what it is trying to express. Also referring to Original and New estimator may be misleading. |
||||||||||||||||||||
|
||||||||||||||||||||
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 | ||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One should measure the cost of the other metrics in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Best approach is to run a simple Q# project, e.g., namespace ResEst {
operation Count() : Unit {
use (a, b, c) = (Qubit(), Qubit(), Qubit());
Microsoft.Quantum.Canon.ApplyAnd(a, b, c);
}
} and run this against the current resources estimator to retrieve the numbers to subtract from the other metrics. |
||||||||||||||||||||
|
||||||||||||||||||||
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 | ||||||||||||||||||||
Comment on lines
+65
to
+75
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest to remove this part and possibly add it as another pull request that targets on making such properties available. |
||||||||||||||||||||
|
||||||||||||||||||||
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; | ||||||||||||||||||||
} | ||||||||||||||||||||
Comment on lines
+77
to
+85
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||
} | ||||||||||||||||||||
} |
Uh oh!
There was an error while loading. Please reload this page.