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

Commit 4f3147b

Browse files
committed
Add new files
1 parent 0eb449a commit 4f3147b

File tree

3 files changed

+241
-0
lines changed

3 files changed

+241
-0
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#nullable enable
2+
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Diagnostics.CodeAnalysis;
6+
using System.Linq;
7+
using Microsoft.Quantum.Simulation.Core;
8+
using Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime;
9+
using Microsoft.Quantum.Simulation.Simulators;
10+
using Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators;
11+
12+
namespace Simulator
13+
{
14+
public class ResourcesEstimatorWithAdditionalPrimitiveOperations : ResourcesEstimator
15+
{
16+
public ResourcesEstimatorWithAdditionalPrimitiveOperations() : this(ResourcesEstimator.RecommendedConfig())
17+
{
18+
}
19+
20+
public ResourcesEstimatorWithAdditionalPrimitiveOperations(QCTraceSimulatorConfiguration config) : base(WithoutPrimitiveOperationsCounter(config))
21+
{
22+
}
23+
24+
private static QCTraceSimulatorConfiguration WithoutPrimitiveOperationsCounter(QCTraceSimulatorConfiguration config)
25+
{
26+
config.UsePrimitiveOperationsCounter = false;
27+
return config;
28+
}
29+
30+
protected virtual IDictionary<string, IEnumerable<Type>>? AdditionalOperations { get; }
31+
32+
protected override void InitializeQCTracerCoreListeners(IList<IQCTraceSimulatorListener> listeners)
33+
{
34+
base.InitializeQCTracerCoreListeners(listeners);
35+
36+
// add custom primitive operations listener
37+
var primitiveOperationsIdToNames = new Dictionary<int, string>();
38+
Utils.FillDictionaryForEnumNames<PrimitiveOperationsGroups, int>(primitiveOperationsIdToNames);
39+
40+
var operationNameToId = new Dictionary<string, int>();
41+
42+
if (AdditionalOperations != null)
43+
{
44+
foreach (var name in AdditionalOperations.Keys)
45+
{
46+
var id = primitiveOperationsIdToNames.Count;
47+
operationNameToId[name] = id;
48+
primitiveOperationsIdToNames.Add(id, name);
49+
}
50+
}
51+
52+
var cfg = new PrimitiveOperationsCounterConfiguration { primitiveOperationsNames = primitiveOperationsIdToNames.Values.ToArray() };
53+
var operationsCounter = new PrimitiveOperationsCounter(cfg);
54+
tCoreConfig.Listeners.Add(operationsCounter);
55+
56+
if (AdditionalOperations != null)
57+
{
58+
var compare = new AssignableTypeComparer();
59+
this.OnOperationStart += (callable, data) => {
60+
var unwrapped = callable.UnwrapCallable();
61+
foreach (var (name, types) in AdditionalOperations)
62+
{
63+
if (types.Contains(unwrapped.GetType(), compare))
64+
{
65+
var adjName = $"Adjoint{name}";
66+
67+
var key = (callable.Variant == OperationFunctor.Adjoint || callable.Variant == OperationFunctor.ControlledAdjoint) && AdditionalOperations.ContainsKey(adjName)
68+
? adjName
69+
: name;
70+
71+
operationsCounter.OnPrimitiveOperation(operationNameToId[key], new object[] { }, 0.0);
72+
break;
73+
}
74+
}
75+
};
76+
}
77+
}
78+
79+
private class AssignableTypeComparer : IEqualityComparer<Type>
80+
{
81+
public bool Equals([AllowNull] Type x, [AllowNull] Type y)
82+
{
83+
return x != null && x.IsAssignableFrom(y);
84+
}
85+
86+
public int GetHashCode([DisallowNull] Type obj)
87+
{
88+
return obj.GetHashCode();
89+
}
90+
}
91+
}
92+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#nullable enable
2+
3+
using System.Collections.Generic;
4+
using System.Diagnostics;
5+
using Microsoft.Quantum.Simulation.Core;
6+
using Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime;
7+
8+
namespace Simulator
9+
{
10+
public class RuntimeCounter : IQCTraceSimulatorListener, ICallGraphStatistics
11+
{
12+
public RuntimeCounter()
13+
{
14+
AddToCallStack(CallGraphEdge.CallGraphRootHashed, OperationFunctor.Body);
15+
stats = new StatisticsCollector<CallGraphEdge>(
16+
new [] { "Runtime" },
17+
StatisticsCollector<CallGraphEdge>.DefaultStatistics()
18+
);
19+
}
20+
21+
public bool NeedsTracingDataInQubits => false;
22+
23+
public object? NewTracingData(long qubitId) => null;
24+
25+
public void OnAllocate(object[] qubitsTraceData) {}
26+
27+
public void OnRelease(object[] qubitsTraceData) {}
28+
29+
public void OnBorrow(object[] qubitsTraceData, long newQubitsAllocated) {}
30+
31+
public void OnReturn(object[] qubitsTraceData, long qubitReleased) {}
32+
33+
public void OnOperationStart(HashedString name, OperationFunctor variant, object[] qubitsTraceData)
34+
{
35+
AddToCallStack(name, variant);
36+
operationCallStack.Peek().Watch.Start();
37+
}
38+
39+
public void OnOperationEnd(object[] returnedQubitsTraceData)
40+
{
41+
var record = operationCallStack.Pop();
42+
record.Watch.Stop();
43+
Debug.Assert(operationCallStack.Count != 0, "Operation call stack must never get empty");
44+
stats.AddSample(new CallGraphEdge(record.OperationName, operationCallStack.Peek().OperationName, record.FunctorSpecialization, operationCallStack.Peek().FunctorSpecialization), new [] { (double)record.Watch.ElapsedMilliseconds });
45+
}
46+
47+
public void OnPrimitiveOperation(int id, object[] qubitsTraceData, double primitiveOperationDuration) {}
48+
49+
public IStatisticCollectorResults<CallGraphEdge> Results { get => stats as IStatisticCollectorResults<CallGraphEdge>; }
50+
51+
private record OperationCallRecord(HashedString OperationName, OperationFunctor FunctorSpecialization)
52+
{
53+
public Stopwatch Watch { get; } = new();
54+
}
55+
56+
private readonly Stack<OperationCallRecord> operationCallStack = new Stack<OperationCallRecord>();
57+
private readonly StatisticsCollector<CallGraphEdge> stats;
58+
59+
private void AddToCallStack(HashedString operationName, OperationFunctor functorSpecialization) =>
60+
operationCallStack.Push(new OperationCallRecord(operationName, functorSpecialization));
61+
}
62+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Data;
4+
using Microsoft.Quantum.Simulation.Simulators;
5+
using Microsoft.Quantum.Simulation.Core;
6+
using Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime;
7+
using Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators;
8+
9+
// using System.IO;
10+
// using System.Threading.Tasks;
11+
12+
namespace Simulator
13+
{
14+
public class AdvancedSimulator : ResourcesEstimatorWithAdditionalPrimitiveOperations
15+
{
16+
// public override Task<O> Run<T, I, O>(I args)
17+
// {
18+
// var result = base.Run<T, I, O>(args).Result;
19+
// var name = typeof(T).Name;
20+
// File.WriteAllText($"{name}.txt", ToTSV());
21+
// return Task.Run(() => result);
22+
// }
23+
24+
protected override IDictionary<string, IEnumerable<Type>> AdditionalOperations { get; } =
25+
new Dictionary<string, IEnumerable<Type>> {
26+
["CCZ"] = new [] { typeof(Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators.Circuits.CCZ) },
27+
["And"] = new [] { typeof(Microsoft.Quantum.Canon.ApplyAnd), typeof(Microsoft.Quantum.Canon.ApplyLowDepthAnd) },
28+
["AdjointAnd"] = Array.Empty<Type>()
29+
};
30+
31+
protected override void InitializeQCTracerCoreListeners(IList<IQCTraceSimulatorListener> listeners)
32+
{
33+
base.InitializeQCTracerCoreListeners(listeners);
34+
tCoreConfig.Listeners.Add(new RuntimeCounter());
35+
}
36+
37+
// CCNOT(a, b, c);
38+
// T(a);
39+
// T(b);
40+
41+
// Original QDK ResEst. -> 9 Ts
42+
// New QDK ResEst. -> 1 CCZ, 2 Ts
43+
44+
public override DataTable Data
45+
{
46+
get
47+
{
48+
var data = base.Data;
49+
50+
var androw = data.Rows.Find("And");
51+
var adjandrow = data.Rows.Find("AdjointAnd");
52+
var cczrow = data.Rows.Find("CCZ");
53+
var trow = data.Rows.Find("T");
54+
55+
// Update T count
56+
trow["Sum"] = (double)trow["Sum"] - 4 * (double)androw["Sum"] - 7 * (double)cczrow["Sum"];
57+
trow["Max"] = (double)trow["Max"] - 4 * (double)androw["Max"] - 7 * (double)cczrow["Max"];
58+
59+
// TODO: update CNOT, QubitClifford, and Measure as well
60+
61+
return data;
62+
}
63+
}
64+
65+
#region Direct access to counts
66+
public long CNOT => (long)(double)Data!.Rows!.Find("CNOT")![1];
67+
public long QubitClifford => (long)(double)Data!.Rows!.Find("QubitClifford")![1];
68+
public long T => (long)(double)Data!.Rows!.Find("T")![1];
69+
public long Measure => (long)(double)Data!.Rows!.Find("Measure")![1];
70+
public long QubitCount => (long)(double)Data!.Rows!.Find("QubitCount")![1];
71+
public long Depth => (long)(double)Data!.Rows!.Find("Depth")![1];
72+
public long CCZ => (long)(double)Data!.Rows!.Find("CCZ")![1];
73+
public long And => (long)(double)Data!.Rows!.Find("And")![1];
74+
public long AdjointAnd => (long)(double)Data!.Rows!.Find("AdjointAnd")![1];
75+
#endregion
76+
77+
public override O Execute<T, I, O>(I args)
78+
{
79+
var result = base.Execute<T, I, O>(args);
80+
Console.WriteLine("");
81+
Console.WriteLine("---BEGIN TABLE---");
82+
Console.WriteLine(ToTSV());
83+
Console.WriteLine("---END TABLE---");
84+
return result;
85+
}
86+
}
87+
}

0 commit comments

Comments
 (0)