blob: 964489478e73a627b91686c64245f1b086632c77 [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 <armnn/utility/IgnoreUnused.hpp>
7#include <FileOnlyProfilingConnection.hpp>
8#include <Filesystem.hpp>
9#include <NullProfilingConnection.hpp>
Aron Virginas-Tar8bf442e2019-11-07 18:41:40 +000010#include <ProfilingService.hpp>
Keith Davis3201eea2019-10-24 17:30:41 +010011#include <Runtime.hpp>
Jim Flynn4e755a52020-03-29 17:48:26 +010012#include "PrintPacketHeaderHandler.hpp"
13#include "TestTimelinePacketHandler.hpp"
Keith Davis3201eea2019-10-24 17:30:41 +010014
Keith Davis3201eea2019-10-24 17:30:41 +010015#include <boost/filesystem.hpp>
16#include <boost/numeric/conversion/cast.hpp>
17#include <boost/test/unit_test.hpp>
18
Keith Davis3201eea2019-10-24 17:30:41 +010019#include <cstdio>
20#include <fstream>
21#include <sstream>
22#include <sys/stat.h>
23
Keith Davis3201eea2019-10-24 17:30:41 +010024using namespace armnn::profiling;
25using namespace armnn;
26
27using namespace std::chrono_literals;
28
Finn Williams09ad6f92019-12-19 17:05:18 +000029class FileOnlyHelperService : public ProfilingService
30{
31 public:
32 // Wait for a notification from the send thread
33 bool WaitForPacketsSent(uint32_t timeout = 1000)
34 {
Sadik Armagan3184c902020-03-18 10:57:30 +000035 return ProfilingService::WaitForPacketSent(m_ProfilingService, timeout);
Finn Williams09ad6f92019-12-19 17:05:18 +000036 }
Sadik Armagan3184c902020-03-18 10:57:30 +000037 armnn::profiling::ProfilingService m_ProfilingService;
Finn Williams09ad6f92019-12-19 17:05:18 +000038};
39
Keith Davis3201eea2019-10-24 17:30:41 +010040BOOST_AUTO_TEST_SUITE(FileOnlyProfilingDecoratorTests)
41
Jim Flynn4e755a52020-03-29 17:48:26 +010042std::string UniqueFileName()
43{
44 std::time_t t = std::time(nullptr);
45 char mbstr[100];
46 std::strftime(mbstr, sizeof(mbstr), "%Y_%m_%d_%H_%M_%S_", std::localtime(&t));
47 std::stringstream ss;
48 ss << mbstr;
49 ss << t;
50 ss << ".bin";
51 return ss.str();
52}
53
54BOOST_AUTO_TEST_CASE(TestFileOnlyProfiling)
55{
56 // Create a temporary file name.
57 boost::filesystem::path tempPath = boost::filesystem::temp_directory_path();
58 boost::filesystem::path tempFile = UniqueFileName();
59 tempPath = tempPath / tempFile;
60 armnn::Runtime::CreationOptions creationOptions;
61 creationOptions.m_ProfilingOptions.m_EnableProfiling = true;
62 creationOptions.m_ProfilingOptions.m_FileOnly = true;
63 creationOptions.m_ProfilingOptions.m_CapturePeriod = 100;
64 creationOptions.m_ProfilingOptions.m_TimelineEnabled = true;
65 ILocalPacketHandlerSharedPtr localPacketHandlerPtr = std::make_shared<TestTimelinePacketHandler>();
66 creationOptions.m_ProfilingOptions.m_LocalPacketHandlers.push_back(localPacketHandlerPtr);
67
68 armnn::Runtime runtime(creationOptions);
69
70 // Load a simple network
71 // build up the structure of the network
72 INetworkPtr net(INetwork::Create());
73
74 IConnectableLayer* input = net->AddInputLayer(0, "input");
75
76 NormalizationDescriptor descriptor;
77 IConnectableLayer* normalize = net->AddNormalizationLayer(descriptor, "normalization");
78
79 IConnectableLayer* output = net->AddOutputLayer(0, "output");
80
81 input->GetOutputSlot(0).Connect(normalize->GetInputSlot(0));
82 normalize->GetOutputSlot(0).Connect(output->GetInputSlot(0));
83
84 input->GetOutputSlot(0).SetTensorInfo(TensorInfo({ 1, 1, 4, 4 }, DataType::Float32));
85 normalize->GetOutputSlot(0).SetTensorInfo(TensorInfo({ 1, 1, 4, 4 }, DataType::Float32));
86
87 // optimize the network
88 std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef };
89 IOptimizedNetworkPtr optNet = Optimize(*net, backends, runtime.GetDeviceSpec());
90
91 // Load it into the runtime. It should succeed.
92 armnn::NetworkId netId;
93 BOOST_TEST(runtime.LoadNetwork(netId, std::move(optNet)) == Status::Success);
94
95 static_cast<TestTimelinePacketHandler*>(localPacketHandlerPtr.get())->WaitOnInferenceCompletion(3000);
96}
97
Jan Eilers158997a2020-01-30 13:50:36 +000098BOOST_AUTO_TEST_CASE(DumpOutgoingValidFileEndToEnd, * boost::unit_test::disabled())
Keith Davis3201eea2019-10-24 17:30:41 +010099{
100 // Create a temporary file name.
101 boost::filesystem::path tempPath = boost::filesystem::temp_directory_path();
Jim Flynn4e755a52020-03-29 17:48:26 +0100102 boost::filesystem::path tempFile = UniqueFileName();
Keith Davis3201eea2019-10-24 17:30:41 +0100103 tempPath = tempPath / tempFile;
104 armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
105 options.m_EnableProfiling = true;
106 options.m_FileOnly = true;
107 options.m_IncomingCaptureFile = "";
Rob Hughes270233f2019-11-13 11:53:48 +0000108 options.m_OutgoingCaptureFile = tempPath.string();
Keith Davis3201eea2019-10-24 17:30:41 +0100109 options.m_CapturePeriod = 100;
110
Finn Williams09ad6f92019-12-19 17:05:18 +0000111 FileOnlyHelperService helper;
112
Keith Davis3201eea2019-10-24 17:30:41 +0100113 // Enable the profiling service
Sadik Armagan3184c902020-03-18 10:57:30 +0000114 armnn::profiling::ProfilingService profilingService;
Keith Davis3201eea2019-10-24 17:30:41 +0100115 profilingService.ResetExternalProfilingOptions(options, true);
116 // Bring the profiling service to the "WaitingForAck" state
117 profilingService.Update();
118 profilingService.Update();
119
Keith Davis3201eea2019-10-24 17:30:41 +0100120
Finn Williams09ad6f92019-12-19 17:05:18 +0000121 BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
Keith Davis3201eea2019-10-24 17:30:41 +0100122
123 profilingService.Update();
Finn Williams09ad6f92019-12-19 17:05:18 +0000124 // First packet sent will be the SendStreamMetaDataPacket, it's possible though unlikely that it will be sent twice
125 // The second or possibly third packet will be the CounterDirectoryPacket which means the
126 // ConnectionAcknowledgedCommandHandler has set the state to active
127 uint32_t packetCount = 0;
128 while(profilingService.GetCurrentState() != ProfilingState::Active && packetCount < 3)
Keith Davis3201eea2019-10-24 17:30:41 +0100129 {
Finn Williams09ad6f92019-12-19 17:05:18 +0000130 if(!helper.WaitForPacketsSent())
Keith Davis3201eea2019-10-24 17:30:41 +0100131 {
Finn Williams09ad6f92019-12-19 17:05:18 +0000132 BOOST_FAIL("Timeout waiting for packets");
Keith Davis3201eea2019-10-24 17:30:41 +0100133 }
Finn Williams09ad6f92019-12-19 17:05:18 +0000134 packetCount++;
Keith Davis3201eea2019-10-24 17:30:41 +0100135 }
136
Finn Williams09ad6f92019-12-19 17:05:18 +0000137 BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
Keith Davis3201eea2019-10-24 17:30:41 +0100138 // Minimum test here is to check that the file was created.
139 BOOST_CHECK(boost::filesystem::exists(tempPath.c_str()) == true);
140
141 // Increment a counter.
142 BOOST_CHECK(profilingService.IsCounterRegistered(0) == true);
143 profilingService.IncrementCounterValue(0);
144 BOOST_CHECK(profilingService.GetCounterValue(0) > 0);
145
146 // At this point the profiling service is active and we've activated all the counters. Waiting a collection
147 // period should be enough to have some data in the file.
148
149 // Wait for 1 collection period plus a bit of overhead..
Finn Williams09ad6f92019-12-19 17:05:18 +0000150 helper.WaitForPacketsSent();
Keith Davis3201eea2019-10-24 17:30:41 +0100151
152 // In order to flush the files we need to gracefully close the profiling service.
153 options.m_EnableProfiling = false;
154 profilingService.ResetExternalProfilingOptions(options, true);
Keith Davis3201eea2019-10-24 17:30:41 +0100155
156 // The output file size should be greater than 0.
Rob Hughesbdee4262020-01-07 17:05:24 +0000157 BOOST_CHECK(armnnUtils::Filesystem::GetFileSize(tempPath.string().c_str()) > 0);
Keith Davis3201eea2019-10-24 17:30:41 +0100158
159 // Delete the tmp file.
Rob Hughesbdee4262020-01-07 17:05:24 +0000160 BOOST_CHECK(armnnUtils::Filesystem::Remove(tempPath.string().c_str()));
Keith Davis3201eea2019-10-24 17:30:41 +0100161}
162
163BOOST_AUTO_TEST_SUITE_END()