-
Notifications
You must be signed in to change notification settings - Fork 47
/
Copy pathform1.cs
320 lines (272 loc) · 10.9 KB
/
form1.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
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
// =============================================================================
// <copyright file="Form1.cs" company="Advanced Micro Devices, Inc.">
// Copyright (c) 2011-2020 Advanced Micro Devices, Inc. All rights reserved.
// </copyright>
// <author>
// AMD Developer Tools Team
// </author>
// <summary>
// Main form for PublicCounterCompiler
// </summary>
// =============================================================================
namespace PublicCounterCompiler
{
using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
using Microsoft.Win32;
/// <summary>
/// the main form of the PublicCounterCompiler
/// </summary>
public partial class Form1 : Form
{
/// <summary>
/// the singleton instance
/// </summary>
private static Form1 _instance = null;
/// <summary>
/// Registry key root for the utility
/// </summary>
private static string _registryKey = "HKEY_CURRENT_USER\\Software\\AMD\\DevTools";
/// <summary>
/// Previously entered API
/// </summary>
private static string _registryApiEntry = "PccApi";
/// <summary>
/// Previously entered GPU family
/// </summary>
private static string _registryGpuFamilyEntry = "PccGpuFamily";
/// <summary>
/// Background worker thread
/// </summary>
private static BackgroundWorker _backgroundWorker = new BackgroundWorker();
/// <summary>
/// Background worker thread arguments
/// </summary>
private static BackgroundWorkerArgs _backgroundWorkerArgs;
/// <summary>
/// Counter compiler instance
/// </summary>
public CounterCompiler _counterCompiler;
/// <summary>
/// Initializes a new instance of the Form1 class.
/// </summary>
public Form1(CounterCompiler counterCompiler)
{
_counterCompiler = counterCompiler;
InitializeComponent();
apiName.Text = (string)Registry.GetValue(_registryKey, _registryApiEntry, string.Empty);
GPUFamily.Text = (string)Registry.GetValue(_registryKey, _registryGpuFamilyEntry, string.Empty);
CompileButton.Text = "Compile " + counterCompiler.derivedCounterFileInput.compiler_type_str + " Counters";
_backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_CompileCounters);
_backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_CompileCountersCompleted);
}
/// <summary>
/// Accessor to the singleton instance
/// </summary>
/// <returns>The instance of the form</returns>
public static Form1 Instance(CounterCompiler counterCompiler)
{
if (_instance == null)
{
_instance = new Form1(counterCompiler);
}
return _instance;
}
/// <summary>
/// Determines whether invalid counters should be ignored
/// </summary>
/// <returns>True if invalid counters should be ignored</returns>
public static bool GetIgnoreInvalidCounters
{
get
{
return _instance.IgnoreInvalidCountersCheckBox.Checked;
}
}
/// <summary>
/// Adds a message to the output window
/// </summary>
/// <param name="message">The message to add to the output window</param>
public bool DisplayMessageHandler(string message)
{
if (_counterCompiler.isConsoleApp)
{
Console.Out.Write(message);
}
else
{
// Invoke is used as this may be called from the worker thread
BeginInvoke((Action)(() =>
{
richTextBoxOutput.Text += message + "\n";
richTextBoxOutput.SelectionStart = richTextBoxOutput.Text.Length;
richTextBoxOutput.ScrollToCaret();
}));
}
System.Diagnostics.Debug.Print(message);
return true;
}
/// <summary>
/// Lambda callback error handler used by RegSpec file loading
/// </summary>
/// <param name="message">Error message.</param>
/// <returns>true if any additional error handling occurred, otherwise false.</returns>
public bool ErrorHandler(string message)
{
if (_counterCompiler.isConsoleApp)
{
Console.Out.Write("Error:" + message);
}
else
{
// Invoke is used as this may be called from the worker thread
BeginInvoke((Action)(() =>
{
richTextBoxOutput.Text += "Error:" + message + "\n";
richTextBoxOutput.SelectionStart = richTextBoxOutput.Text.Length;
richTextBoxOutput.ScrollToCaret();
}));
}
System.Diagnostics.Debug.Print("Error:" + message);
return false;
}
/// <summary>
/// Ensures that the apiName and GPUFamily fields are not empty, then
/// compiles the associated counters
/// </summary>
/// <param name="sender">the compile button</param>
/// <param name="e">default event args</param>
private void CompileButton_Click(object sender, EventArgs e)
{
richTextBoxOutput.Text = "";
string api = apiName.Text.Trim();
string gpu = GPUFamily.Text.Trim();
if (string.IsNullOrEmpty(api) ||
string.IsNullOrEmpty(gpu))
{
MessageBox.Show("Required data not provided.\nPlease fill in all the fields on the form.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
Registry.SetValue(_registryKey, _registryApiEntry, api);
Registry.SetValue(_registryKey, _registryGpuFamilyEntry, gpu);
StartCompileCounters(api, gpu);
}
/// <summary>
/// Ensures that the batchApiList and batchGpuFamilyList fields are not empty, then
/// compiles the permutations of associated counters
/// </summary>
/// <param name="sender">the compile button</param>
/// <param name="e">default event args</param>
private void BatchCompile_Click(object sender, EventArgs e)
{
richTextBoxOutput.Text = "";
_counterCompiler.StartRSTDocumentation();
if (string.IsNullOrEmpty(batchApiList.Text.Trim())
|| string.IsNullOrEmpty(batchGpuFamilyList.Text.Trim()))
{
MessageBox.Show("Required data not provided.\nPlease fill in all the fields on the form.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
string[] apis = batchApiList.Text.Trim().Split(',');
string[] gpus = batchGpuFamilyList.Text.Trim().Split(',');
foreach (var api in apis)
{
foreach (var gpu in gpus)
{
var doneEvent = new AutoResetEvent(false);
StartCompileCounters(api, gpu, doneEvent);
// Wait with timeout so we can pump the UI update
while (false == doneEvent.WaitOne(100))
{
Application.DoEvents();
}
}
}
_counterCompiler.DoneRSTDocumentation(DisplayMessageHandler, ErrorHandler);
}
/// <summary>
/// Background worker arguments
/// </summary>
private class BackgroundWorkerArgs
{
/// <summary>
/// Ctor
/// </summary>
/// <param name="_api">API</param>
/// <param name="_gpu">GPU ASIC</param>
/// <param name="_doneEvent">Optional done event</param>
public BackgroundWorkerArgs(string _api, string _gpu, AutoResetEvent _doneEvent)
{
api = _api;
gpu = _gpu;
doneEvent = _doneEvent;
}
/// <summary>
/// API
/// </summary>
public string api;
/// <summary>
/// GPU ASIC
/// </summary>
public string gpu;
/// <summary>
/// Optional done event
/// </summary>
public AutoResetEvent doneEvent = null;
}
/// <summary>
/// Starts background worker thread to compile counters
/// </summary>
/// <param name="api">API</param>
/// <param name="gpu">GPU</param>
/// <param name="autoResetEvent">Optional reset event</param>
private void StartCompileCounters(string api, string gpu, AutoResetEvent autoResetEvent = null)
{
CompileButton.Enabled = false;
batchCompile.Enabled = false;
_backgroundWorkerArgs = new BackgroundWorkerArgs(api, gpu, autoResetEvent);
// Start the asynchronous operation.
_backgroundWorker.RunWorkerAsync(_backgroundWorkerArgs);
}
/// <summary>
/// Background worker compile counters
/// </summary>
/// <param name="sender">Sender object</param>
/// <param name="e">Work event args</param>
private void backgroundWorker_CompileCounters(object sender, DoWorkEventArgs e)
{
// Get the BackgroundWorker that raised this event.
BackgroundWorker worker = sender as BackgroundWorker;
var args = e.Argument as BackgroundWorkerArgs;
DisplayMessageHandler("\nCompiling API " + args.api + " for GPU Family " + args.gpu);
_counterCompiler.CompileCounters(args.api, args.gpu, DisplayMessageHandler, ErrorHandler);
}
/// <summary>
/// Background worker counter compilation completed
/// </summary>
/// <param name="sender">Sender object</param>
/// <param name="e">Completed work event args</param>
private void backgroundWorker_CompileCountersCompleted(object sender, RunWorkerCompletedEventArgs e)
{
CompileButton.Enabled = true;
batchCompile.Enabled = true;
if (null != _backgroundWorkerArgs.doneEvent)
{
_backgroundWorkerArgs.doneEvent.Set();
}
}
/// <summary>
/// Gets the checked state of the Generate Counter Docs button.
/// </summary>
/// <returns>True if counter docs should be generated</returns>
static public bool GenerateCounterDocs
{
get
{
return _instance.checkBoxGenerateCounterDocs.Checked;
}
}
}
}