blob: aa877a10e98f3110e0a111ca6423639ebf95d353 [file] [log] [blame]
Keith Davis3201eea2019-10-24 17:30:41 +01001//
2// Copyright © 2019 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
Jim Flynn4e755a52020-03-29 17:48:26 +01006#include <Filesystem.hpp>
Aron Virginas-Tar8bf442e2019-11-07 18:41:40 +00007#include <ProfilingService.hpp>
Keith Davis3201eea2019-10-24 17:30:41 +01008#include <Runtime.hpp>
Jim Flynn4e755a52020-03-29 17:48:26 +01009#include "PrintPacketHeaderHandler.hpp"
10#include "TestTimelinePacketHandler.hpp"
Keith Davis3201eea2019-10-24 17:30:41 +010011
Keith Davis3201eea2019-10-24 17:30:41 +010012#include <boost/filesystem.hpp>
13#include <boost/numeric/conversion/cast.hpp>
14#include <boost/test/unit_test.hpp>
15
Keith Davis3201eea2019-10-24 17:30:41 +010016#include <cstdio>
Keith Davis3201eea2019-10-24 17:30:41 +010017#include <sstream>
18#include <sys/stat.h>
19
Keith Davis3201eea2019-10-24 17:30:41 +010020using namespace armnn::profiling;
21using namespace armnn;
22
23using namespace std::chrono_literals;
24
Finn Williams09ad6f92019-12-19 17:05:18 +000025class FileOnlyHelperService : public ProfilingService
26{
27 public:
28 // Wait for a notification from the send thread
29 bool WaitForPacketsSent(uint32_t timeout = 1000)
30 {
Sadik Armagan3184c902020-03-18 10:57:30 +000031 return ProfilingService::WaitForPacketSent(m_ProfilingService, timeout);
Finn Williams09ad6f92019-12-19 17:05:18 +000032 }
Sadik Armagan3184c902020-03-18 10:57:30 +000033 armnn::profiling::ProfilingService m_ProfilingService;
Finn Williams09ad6f92019-12-19 17:05:18 +000034};
35
Keith Davis3201eea2019-10-24 17:30:41 +010036BOOST_AUTO_TEST_SUITE(FileOnlyProfilingDecoratorTests)
37
Jim Flynn4e755a52020-03-29 17:48:26 +010038std::string UniqueFileName()
39{
40 std::time_t t = std::time(nullptr);
41 char mbstr[100];
42 std::strftime(mbstr, sizeof(mbstr), "%Y_%m_%d_%H_%M_%S_", std::localtime(&t));
43 std::stringstream ss;
44 ss << mbstr;
45 ss << t;
46 ss << ".bin";
47 return ss.str();
48}
49
50BOOST_AUTO_TEST_CASE(TestFileOnlyProfiling)
51{
Jim Flynn01d02812020-04-29 21:12:13 +010052 // This test requires at least one backend registry to be enabled
53 // which can execute a NormalizationLayer
54 if (BackendRegistryInstance().IsBackendRegistered(GetComputeDeviceAsCString(armnn::Compute::CpuRef)) ||
55 BackendRegistryInstance().IsBackendRegistered(GetComputeDeviceAsCString(armnn::Compute::CpuAcc)) ||
56 BackendRegistryInstance().IsBackendRegistered(GetComputeDeviceAsCString(armnn::Compute::GpuAcc)))
Finn Williams0c32ccf2020-05-12 13:37:06 +010057 {
58 return;
59 }
60
Jim Flynn4e755a52020-03-29 17:48:26 +010061 // Create a temporary file name.
62 boost::filesystem::path tempPath = boost::filesystem::temp_directory_path();
63 boost::filesystem::path tempFile = UniqueFileName();
64 tempPath = tempPath / tempFile;
65 armnn::Runtime::CreationOptions creationOptions;
66 creationOptions.m_ProfilingOptions.m_EnableProfiling = true;
67 creationOptions.m_ProfilingOptions.m_FileOnly = true;
68 creationOptions.m_ProfilingOptions.m_CapturePeriod = 100;
69 creationOptions.m_ProfilingOptions.m_TimelineEnabled = true;
70 ILocalPacketHandlerSharedPtr localPacketHandlerPtr = std::make_shared<TestTimelinePacketHandler>();
71 creationOptions.m_ProfilingOptions.m_LocalPacketHandlers.push_back(localPacketHandlerPtr);
72
73 armnn::Runtime runtime(creationOptions);
74
75 // Load a simple network
76 // build up the structure of the network
77 INetworkPtr net(INetwork::Create());
78
79 IConnectableLayer* input = net->AddInputLayer(0, "input");
80
81 NormalizationDescriptor descriptor;
82 IConnectableLayer* normalize = net->AddNormalizationLayer(descriptor, "normalization");
83
84 IConnectableLayer* output = net->AddOutputLayer(0, "output");
85
86 input->GetOutputSlot(0).Connect(normalize->GetInputSlot(0));
87 normalize->GetOutputSlot(0).Connect(output->GetInputSlot(0));
88
89 input->GetOutputSlot(0).SetTensorInfo(TensorInfo({ 1, 1, 4, 4 }, DataType::Float32));
90 normalize->GetOutputSlot(0).SetTensorInfo(TensorInfo({ 1, 1, 4, 4 }, DataType::Float32));
91
92 // optimize the network
Jim Flynn01d02812020-04-29 21:12:13 +010093 std::vector<armnn::BackendId> backends =
94 { armnn::Compute::CpuRef, armnn::Compute::CpuAcc, armnn::Compute::GpuAcc };
Jim Flynn4e755a52020-03-29 17:48:26 +010095 IOptimizedNetworkPtr optNet = Optimize(*net, backends, runtime.GetDeviceSpec());
96
97 // Load it into the runtime. It should succeed.
98 armnn::NetworkId netId;
99 BOOST_TEST(runtime.LoadNetwork(netId, std::move(optNet)) == Status::Success);
100
Jim Flynn01d02812020-04-29 21:12:13 +0100101 // Creates structures for input & output.
102 std::vector<float> inputData(16);
103 std::vector<float> outputData(16);
104
105 InputTensors inputTensors
106 {
107 {0, ConstTensor(runtime.GetInputTensorInfo(netId, 0), inputData.data())}
108 };
109 OutputTensors outputTensors
110 {
111 {0, Tensor(runtime.GetOutputTensorInfo(netId, 0), outputData.data())}
112 };
113
114 // Does the inference.
115 runtime.EnqueueWorkload(netId, inputTensors, outputTensors);
116
Jim Flynn4e755a52020-03-29 17:48:26 +0100117 static_cast<TestTimelinePacketHandler*>(localPacketHandlerPtr.get())->WaitOnInferenceCompletion(3000);
118}
119
Jan Eilers158997a2020-01-30 13:50:36 +0000120BOOST_AUTO_TEST_CASE(DumpOutgoingValidFileEndToEnd, * boost::unit_test::disabled())
Keith Davis3201eea2019-10-24 17:30:41 +0100121{
122 // Create a temporary file name.
123 boost::filesystem::path tempPath = boost::filesystem::temp_directory_path();
Jim Flynn4e755a52020-03-29 17:48:26 +0100124 boost::filesystem::path tempFile = UniqueFileName();
Keith Davis3201eea2019-10-24 17:30:41 +0100125 tempPath = tempPath / tempFile;
126 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
127 options.m_EnableProfiling = true;
128 options.m_FileOnly = true;
129 options.m_IncomingCaptureFile = "";
Rob Hughes270233f2019-11-13 11:53:48 +0000130 options.m_OutgoingCaptureFile = tempPath.string();
Keith Davis3201eea2019-10-24 17:30:41 +0100131 options.m_CapturePeriod = 100;
132
Finn Williams09ad6f92019-12-19 17:05:18 +0000133 FileOnlyHelperService helper;
134
Keith Davis3201eea2019-10-24 17:30:41 +0100135 // Enable the profiling service
Sadik Armagan3184c902020-03-18 10:57:30 +0000136 armnn::profiling::ProfilingService profilingService;
Keith Davis3201eea2019-10-24 17:30:41 +0100137 profilingService.ResetExternalProfilingOptions(options, true);
138 // Bring the profiling service to the "WaitingForAck" state
139 profilingService.Update();
140 profilingService.Update();
141
Keith Davis3201eea2019-10-24 17:30:41 +0100142
Finn Williams09ad6f92019-12-19 17:05:18 +0000143 BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +0100144
145 profilingService.Update();
Finn Williams09ad6f92019-12-19 17:05:18 +0000146 // First packet sent will be the SendStreamMetaDataPacket, it's possible though unlikely that it will be sent twice
147 // The second or possibly third packet will be the CounterDirectoryPacket which means the
148 // ConnectionAcknowledgedCommandHandler has set the state to active
149 uint32_t packetCount = 0;
150 while(profilingService.GetCurrentState() != ProfilingState::Active && packetCount < 3)
Keith Davis3201eea2019-10-24 17:30:41 +0100151 {
Finn Williams09ad6f92019-12-19 17:05:18 +0000152 if(!helper.WaitForPacketsSent())
Keith Davis3201eea2019-10-24 17:30:41 +0100153 {
Finn Williams09ad6f92019-12-19 17:05:18 +0000154 BOOST_FAIL("Timeout waiting for packets");
Keith Davis3201eea2019-10-24 17:30:41 +0100155 }
Finn Williams09ad6f92019-12-19 17:05:18 +0000156 packetCount++;
Keith Davis3201eea2019-10-24 17:30:41 +0100157 }
158
Finn Williams09ad6f92019-12-19 17:05:18 +0000159 BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Keith Davis3201eea2019-10-24 17:30:41 +0100160 // Minimum test here is to check that the file was created.
161 BOOST_CHECK(boost::filesystem::exists(tempPath.c_str()) == true);
162
163 // Increment a counter.
164 BOOST_CHECK(profilingService.IsCounterRegistered(0) == true);
165 profilingService.IncrementCounterValue(0);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100166 BOOST_CHECK(profilingService.GetAbsoluteCounterValue(0) > 0);
167 BOOST_CHECK(profilingService.GetDeltaCounterValue(0) > 0);
Keith Davis3201eea2019-10-24 17:30:41 +0100168
169 // At this point the profiling service is active and we've activated all the counters. Waiting a collection
170 // period should be enough to have some data in the file.
171
172 // Wait for 1 collection period plus a bit of overhead..
Finn Williams09ad6f92019-12-19 17:05:18 +0000173 helper.WaitForPacketsSent();
Keith Davis3201eea2019-10-24 17:30:41 +0100174
175 // In order to flush the files we need to gracefully close the profiling service.
176 options.m_EnableProfiling = false;
177 profilingService.ResetExternalProfilingOptions(options, true);
Keith Davis3201eea2019-10-24 17:30:41 +0100178
179 // The output file size should be greater than 0.
Rob Hughesbdee4262020-01-07 17:05:24 +0000180 BOOST_CHECK(armnnUtils::Filesystem::GetFileSize(tempPath.string().c_str()) > 0);
Keith Davis3201eea2019-10-24 17:30:41 +0100181
182 // Delete the tmp file.
Rob Hughesbdee4262020-01-07 17:05:24 +0000183 BOOST_CHECK(armnnUtils::Filesystem::Remove(tempPath.string().c_str()));
Keith Davis3201eea2019-10-24 17:30:41 +0100184}
185
186BOOST_AUTO_TEST_SUITE_END()