Skip to content

Commit 44ead4f

Browse files
authored
Add programmatic capture for PIX tool (#200)
* Add PIX functionality to WinMLRunner * Made comments more descriptive * Added #if and #endif Directives
1 parent a61faf4 commit 44ead4f

File tree

3 files changed

+63
-16
lines changed

3 files changed

+63
-16
lines changed

Tools/WinMLRunner/src/Common.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ enum WINML_MODEL_TEST_PERF
4141

4242
using namespace winrt;
4343

44+
#define THROW_IF_FAILED(hr) \
45+
{ \
46+
if (FAILED(hr)) \
47+
throw hresult_error(hr); \
48+
}
49+
4450
inline std::wstring MakeErrorMsg(HRESULT hr)
4551
{
4652
std::wostringstream ss;

Tools/WinMLRunner/src/OutputHelper.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
#include <direct.h>
1313
#include <queue>
1414

15+
#if defined(_AMD64_)
16+
// PIX markers only work on amd64
17+
#include <DXProgrammableCapture.h>
18+
#endif
19+
1520
using namespace winrt::Windows::AI::MachineLearning;
1621
using namespace winrt::Windows::Storage::Streams;
1722
using namespace ::Windows::Graphics::DirectX::Direct3D11;
@@ -962,7 +967,10 @@ class OutputHelper
962967
std::vector<double> m_clockEvalTimes;
963968

964969
std::wstring getCsvFileNamePerIterationResult() { return m_csvFileNamePerIterationResult; }
965-
970+
#if defined(_AMD64_)
971+
// PIX markers only work on amd64
972+
com_ptr<IDXGraphicsAnalysis>& GetGraphicsAnalysis() { return m_graphicsAnalysis; }
973+
#endif
966974
private:
967975
std::wstring m_csvFileName;
968976
std::wstring m_csvFileNamePerIterationSummary;
@@ -981,4 +989,9 @@ class OutputHelper
981989
std::vector<double> m_GPUDedicatedDiff;
982990
std::vector<std::string> m_outputResult;
983991
std::vector<int> m_outputTensorHash;
992+
993+
#if defined(_AMD64_)
994+
// PIX markers only work on amd64
995+
com_ptr<IDXGraphicsAnalysis> m_graphicsAnalysis = nullptr;
996+
#endif
984997
};

Tools/WinMLRunner/src/Run.cpp

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,13 @@
88
#include "Run.h"
99
#include "Scenarios.h"
1010

11-
#define THROW_IF_FAILED(hr) \
12-
{ \
13-
if (FAILED(hr)) \
14-
throw hresult_error(hr); \
15-
}
1611
using namespace winrt::Windows::Graphics::DirectX::Direct3D11;
1712

1813
LearningModel LoadModel(const std::wstring& path, bool capturePerf, OutputHelper& output, const CommandLineArgs& args,
1914
uint32_t iterationNum, Profiler<WINML_MODEL_TEST_PERF>& profiler)
2015
{
2116
LearningModel model = nullptr;
2217
output.PrintLoadingInfo(path);
23-
2418
try
2519
{
2620
if (capturePerf)
@@ -197,7 +191,15 @@ HRESULT EvaluateModel(const LearningModel& model, const CommandLineArgs& args, O
197191

198192
LearningModelSession session = nullptr;
199193
IDirect3DDevice winrtDevice = nullptr;
200-
194+
#if defined(_AMD64_)
195+
// PIX markers only work on AMD64
196+
if (output.GetGraphicsAnalysis().get())
197+
{
198+
// If PIX tool is attached to WinMLRunner then begin capture. First capture will include
199+
// session creation, first iteration bind and first iteration evaluate.
200+
output.GetGraphicsAnalysis()->BeginCapture();
201+
}
202+
#endif
201203
try
202204
{
203205
if (deviceCreationLocation == DeviceCreationLocation::ClientCode && deviceType != DeviceType::CPU)
@@ -308,6 +310,15 @@ HRESULT EvaluateModel(const LearningModel& model, const CommandLineArgs& args, O
308310
return hr.code();
309311
}
310312

313+
#if defined(_AMD64_)
314+
// PIX markers only work on AMD64
315+
// If PIX tool was attached then capture already began for the first iteration before session creation.
316+
// This is to begin PIX capture for each iteration after the first iteration.
317+
if (i > 0 && output.GetGraphicsAnalysis())
318+
{
319+
output.GetGraphicsAnalysis()->BeginCapture();
320+
}
321+
#endif
311322
HRESULT bindInputResult =
312323
BindInputFeatures(model, context, inputFeatures, args, output, captureIterationPerf, i, profiler);
313324

@@ -344,6 +355,14 @@ HRESULT EvaluateModel(const LearningModel& model, const CommandLineArgs& args, O
344355
completionString = "[SUCCESS]\n";
345356
}
346357
}
358+
#if defined(_AMD64_)
359+
// PIX markers only work on AMD64
360+
if (output.GetGraphicsAnalysis())
361+
{
362+
// If PIX tool is attached, then end the capture
363+
output.GetGraphicsAnalysis()->EndCapture();
364+
}
365+
#endif
347366
}
348367
printf("%s", completionString.c_str());
349368

@@ -360,12 +379,12 @@ HRESULT EvaluateModel(const LearningModel& model, const CommandLineArgs& args, O
360379
}
361380

362381
HRESULT EvaluateModelWithDeviceType(const LearningModel& model, const DeviceType deviceType,
363-
const std::vector<InputBindingType>& inputBindingTypes,
364-
const std::vector<InputDataType>& inputDataTypes,
365-
const std::vector<DeviceCreationLocation> deviceCreationLocations,
366-
const CommandLineArgs& args, const std::wstring& modelPath, OutputHelper& output,
367-
Profiler<WINML_MODEL_TEST_PERF>& profiler,
368-
TensorFeatureDescriptor& tensorDescriptor)
382+
const std::vector<InputBindingType>& inputBindingTypes,
383+
const std::vector<InputDataType>& inputDataTypes,
384+
const std::vector<DeviceCreationLocation> deviceCreationLocations,
385+
const CommandLineArgs& args, const std::wstring& modelPath, OutputHelper& output,
386+
Profiler<WINML_MODEL_TEST_PERF>& profiler,
387+
TensorFeatureDescriptor& tensorDescriptor)
369388
{
370389
for (const auto& inputBindingType : inputBindingTypes)
371390
{
@@ -452,7 +471,7 @@ HRESULT EvaluateModels(const std::vector<std::wstring>& modelPaths, const std::v
452471
{
453472
HRESULT evaluateModelWithDeviceTypeResult =
454473
EvaluateModelWithDeviceType(model, deviceType, inputBindingTypes, inputDataTypes,
455-
deviceCreationLocations, args, path, output, profiler, tensorDescriptor);
474+
deviceCreationLocations, args, path, output, profiler, tensorDescriptor);
456475
if (FAILED(evaluateModelWithDeviceTypeResult))
457476
{
458477
lastEvaluateModelResult = evaluateModelWithDeviceTypeResult;
@@ -553,6 +572,16 @@ int run(CommandLineArgs& args, Profiler<WINML_MODEL_TEST_PERF>& profiler)
553572
winrt::init_apartment();
554573
OutputHelper output(args.NumIterations());
555574

575+
#if defined(_AMD64_)
576+
// PIX markers only work on AMD64
577+
// Check if PIX tool is attached to WinMLRunner
578+
// Try to acquire IDXGraphicsAnalysis - this only succeeds if PIX is attached
579+
if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(output.GetGraphicsAnalysis().put()))))
580+
{
581+
std::cout << "Detected PIX tool is attached to WinMLRunner" << std::endl;
582+
}
583+
#endif
584+
556585
// Profiler is a wrapper class that captures and stores timing and memory usage data on the
557586
// CPU and GPU.
558587
profiler.Enable();
@@ -590,6 +619,5 @@ int run(CommandLineArgs& args, Profiler<WINML_MODEL_TEST_PERF>& profiler)
590619
return EvaluateModels(modelPaths, deviceTypes, inputBindingTypes, inputDataTypes, deviceCreationLocations, args,
591620
output, profiler);
592621
}
593-
594622
return 0;
595623
}

0 commit comments

Comments
 (0)