-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathExporter.cs
More file actions
148 lines (124 loc) · 5.13 KB
/
Exporter.cs
File metadata and controls
148 lines (124 loc) · 5.13 KB
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.Quantum.Intrinsic;
using Microsoft.Quantum.Simulation.Common;
using Microsoft.Quantum.Simulation.Core;
using QSharpCommunity.Simulators.OpenQasmExporter.Circuits;
namespace QSharpCommunity.Simulators.OpenQasmExporter
{
public class Exporter : SimulatorBase, IDisposable
{
class ConsoleToFileWriter : TextWriter, IDisposable
{
public override Encoding Encoding => m_PreviousConsoleOutput.Encoding;
TextWriter m_PreviousConsoleOutput;
FileStream m_OutputFile;
StreamWriter m_StreamWriter;
public ConsoleToFileWriter(TextWriter consoleTextWriter, string outputFileName)
{
m_PreviousConsoleOutput = consoleTextWriter;
try
{
if (!Path.IsPathRooted(outputFileName))
{
// TODO: Figure out how to get output to the same directory that `dotnet run` occurs (e.g. the main project directory)
// Console.WriteLine($"{Directory.GetCurrentDirectory()}");
// outputFileName = $"{Directory.GetCurrentDirectory()}{outputFileName}";
}
m_OutputFile = new FileStream(outputFileName, FileMode.OpenOrCreate, FileAccess.Write);
m_StreamWriter = new StreamWriter(m_OutputFile);
Console.SetOut(this);
}
catch (Exception e)
{
Console.WriteLine($"Cannot open {outputFileName} for writing");
Console.WriteLine(e.Message);
}
}
public override void Write(string message)
{
m_PreviousConsoleOutput.Write(message);
m_StreamWriter.Write(message);
}
public override void WriteLine(string message)
{
m_PreviousConsoleOutput.WriteLine(message);
m_StreamWriter.WriteLine(message);
}
public new void Dispose()
{
Console.SetOut(m_PreviousConsoleOutput);
m_StreamWriter?.Close();
m_OutputFile?.Close();
}
}
public override string Name => nameof(Exporter);
const string k_DefaultOutputFileName = "output.qasm";
const int k_MaxQubits = 32;
ConsoleToFileWriter m_ConsoleToFileWriter;
public Exporter(string outputFileName, TextWriter outputTextWriter)
: base(new QubitManager(k_MaxQubits, true))
{
m_ConsoleToFileWriter = new ConsoleToFileWriter(outputTextWriter, outputFileName);
RegisterPrimitiveOperationsGivenAsCircuits();
Console.WriteLine("OPENQASM 2.0;");
Console.WriteLine("include \"qelib1.inc\";");
Console.WriteLine($"qreg q[{k_MaxQubits}];");
Console.WriteLine($"creg c[{k_MaxQubits}];");
}
public Exporter(TextWriter outputTextWriter)
: this(k_DefaultOutputFileName, outputTextWriter)
{
}
public Exporter(string outputFileName)
: this(outputFileName, Console.Out)
{
}
public Exporter()
: this(Console.Out)
{
}
public void Dispose()
{
m_ConsoleToFileWriter.Dispose();
}
void RegisterPrimitiveOperationsGivenAsCircuits()
{
var primitiveOperationTypes =
from op in typeof(X).Assembly.GetExportedTypes()
where op.IsSubclassOf(typeof(AbstractCallable))
select op;
var primitiveOperationAsCircuits =
from op in typeof(SingleQubitOp<>).Assembly.GetExportedTypes()
where op.IsSubclassOf(typeof(AbstractCallable))
&& op.Namespace == typeof(SingleQubitOp<>).Namespace
select op;
foreach (var operationType in primitiveOperationTypes)
{
var matchingCircuitTypes =
from op in primitiveOperationAsCircuits
where op.Name == operationType.Name
select op;
var numberOfMatchesFound = matchingCircuitTypes.Count();
if (numberOfMatchesFound == 0)
{
// Use a default
if (typeof(Unitary<Qubit>).IsAssignableFrom(operationType))
{
var genericType = typeof(SingleQubitOp<>).MakeGenericType(operationType);
Register(operationType, genericType, typeof(ICallable));
continue;
}
}
Debug.Assert(
numberOfMatchesFound <= 1,
"There should be at most one matching operation.");
if (numberOfMatchesFound == 1)
Register(operationType, matchingCircuitTypes.First(), typeof(ICallable));
}
}
}
}