This repository has been archived by the owner on Jan 12, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 178
/
Internal.cs
93 lines (79 loc) · 3.34 KB
/
Internal.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#nullable enable
using System;
using System.Numerics;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.Quantum.Diagnostics.Emulation;
using Microsoft.Quantum.Simulation.Common;
using Microsoft.Quantum.Simulation.Core;
using Microsoft.Quantum.Simulation.Simulators;
using NumSharp;
using static NumSharp.Slice;
namespace Microsoft.Quantum.Diagnostics
{
internal class ArrayDumper : QuantumSimulator.StateDumper
{
// NB: NumSharp does not yet support complex numbers, so we store data
// as an array with a trailing index of length 2.
internal NumSharp.NDArray? Data = null;
public ArrayDumper(QuantumSimulator sim) : base(sim)
{
}
public override bool Callback([MarshalAs(UnmanagedType.LPStr)] string idx, double real, double img)
{
if (Data == null) throw new Exception("Expected data buffer to be initialized before callback, but it was null.");
Data![(int)(CommonNativeSimulator.DisplayableState.BasisStateLabelToBigInt(idx)), 0] = real;
Data![(int)(CommonNativeSimulator.DisplayableState.BasisStateLabelToBigInt(idx)), 1] = img;
return true;
}
public override bool Dump(IQArray<Qubit>? qubits = null)
{
var count = qubits?.Length ?? Simulator.QubitManager!.AllocatedQubitsCount;
var nQubitsPerRegister = ((int)count / 2);
Data = np.empty(new Shape(1 << ((int)count), 2));
var result = base.Dump(qubits);
// At this point, _data should be filled with the full state
// vector, so let's display it, counting on the right display
// encoder to be there to pack it into a table.
var scaleFactor = System.Math.Sqrt(1 << nQubitsPerRegister);
Data = scaleFactor * Data.reshape(1 << nQubitsPerRegister, 1 << nQubitsPerRegister, 2);
return result;
}
}
internal partial class DumpReferenceAndTarget
{
public class Native : DumpReferenceAndTarget
{
private SimulatorBase? Simulator;
public Native(IOperationFactory m) : base(m)
{
Simulator = m as SimulatorBase;
}
private QVoid DumpUnitaryFromChoiState(QuantumSimulator simulator, IQArray<Qubit> reference, IQArray<Qubit> target)
{
var arrayDumper = new ArrayDumper(simulator);
arrayDumper.Dump(new QArray<Qubit>(reference.Concat(target)));
Simulator?.MaybeDisplayDiagnostic(
new DisplayableUnitaryOperator
{
Data = arrayDumper.Data,
Qubits = target.ToList()
}
);
return QVoid.Instance;
}
public override Func<(IQArray<Qubit>, IQArray<Qubit>), QVoid> __Body__ => __in__ =>
{
var (reference, target) = __in__;
return Simulator switch
{
QuantumSimulator sim => this.DumpUnitaryFromChoiState(sim, reference, target),
// TODO: Add other simulators here as appropriate.
_ => base.__Body__(__in__)
};
};
}
}
}