IVGCVSW-4737 Add check for CpuRef back-end before using it in tests
[platform/upstream/armnn.git] / src / profiling / test / FileOnlyProfilingDecoratorTests.cpp
1 //
2 // Copyright © 2019 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #include <Filesystem.hpp>
7 #include <ProfilingService.hpp>
8 #include <Runtime.hpp>
9 #include "PrintPacketHeaderHandler.hpp"
10 #include "TestTimelinePacketHandler.hpp"
11
12 #include <boost/filesystem.hpp>
13 #include <boost/numeric/conversion/cast.hpp>
14 #include <boost/test/unit_test.hpp>
15
16 #include <cstdio>
17 #include <sstream>
18 #include <sys/stat.h>
19
20 using namespace armnn::profiling;
21 using namespace armnn;
22
23 using namespace std::chrono_literals;
24
25 class FileOnlyHelperService : public ProfilingService
26 {
27     public:
28     // Wait for a notification from the send thread
29     bool WaitForPacketsSent(uint32_t timeout = 1000)
30     {
31         return ProfilingService::WaitForPacketSent(m_ProfilingService, timeout);
32     }
33     armnn::profiling::ProfilingService m_ProfilingService;
34 };
35
36 BOOST_AUTO_TEST_SUITE(FileOnlyProfilingDecoratorTests)
37
38 std::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
50 BOOST_AUTO_TEST_CASE(TestFileOnlyProfiling)
51 {
52     // This test requires the CpuRef backend to be enabled
53     if(!BackendRegistryInstance().IsBackendRegistered("CpuRef"))
54     {
55         return;
56     }
57
58     // Create a temporary file name.
59     boost::filesystem::path tempPath = boost::filesystem::temp_directory_path();
60     boost::filesystem::path tempFile = UniqueFileName();
61     tempPath                         = tempPath / tempFile;
62     armnn::Runtime::CreationOptions creationOptions;
63     creationOptions.m_ProfilingOptions.m_EnableProfiling     = true;
64     creationOptions.m_ProfilingOptions.m_FileOnly            = true;
65     creationOptions.m_ProfilingOptions.m_CapturePeriod       = 100;
66     creationOptions.m_ProfilingOptions.m_TimelineEnabled     = true;
67     ILocalPacketHandlerSharedPtr localPacketHandlerPtr = std::make_shared<TestTimelinePacketHandler>();
68     creationOptions.m_ProfilingOptions.m_LocalPacketHandlers.push_back(localPacketHandlerPtr);
69
70     armnn::Runtime runtime(creationOptions);
71
72     // Load a simple network
73     // build up the structure of the network
74     INetworkPtr net(INetwork::Create());
75
76     IConnectableLayer* input = net->AddInputLayer(0, "input");
77
78     NormalizationDescriptor descriptor;
79     IConnectableLayer* normalize = net->AddNormalizationLayer(descriptor, "normalization");
80
81     IConnectableLayer* output = net->AddOutputLayer(0, "output");
82
83     input->GetOutputSlot(0).Connect(normalize->GetInputSlot(0));
84     normalize->GetOutputSlot(0).Connect(output->GetInputSlot(0));
85
86     input->GetOutputSlot(0).SetTensorInfo(TensorInfo({ 1, 1, 4, 4 }, DataType::Float32));
87     normalize->GetOutputSlot(0).SetTensorInfo(TensorInfo({ 1, 1, 4, 4 }, DataType::Float32));
88
89     // optimize the network
90     std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef };
91     IOptimizedNetworkPtr optNet = Optimize(*net, backends, runtime.GetDeviceSpec());
92
93     // Load it into the runtime. It should succeed.
94     armnn::NetworkId netId;
95     BOOST_TEST(runtime.LoadNetwork(netId, std::move(optNet)) == Status::Success);
96
97     static_cast<TestTimelinePacketHandler*>(localPacketHandlerPtr.get())->WaitOnInferenceCompletion(3000);
98 }
99
100 BOOST_AUTO_TEST_CASE(DumpOutgoingValidFileEndToEnd, * boost::unit_test::disabled())
101 {
102     // Create a temporary file name.
103     boost::filesystem::path tempPath = boost::filesystem::temp_directory_path();
104     boost::filesystem::path tempFile = UniqueFileName();
105     tempPath                         = tempPath / tempFile;
106     armnn::Runtime::CreationOptions::ExternalProfilingOptions options;
107     options.m_EnableProfiling     = true;
108     options.m_FileOnly            = true;
109     options.m_IncomingCaptureFile = "";
110     options.m_OutgoingCaptureFile = tempPath.string();
111     options.m_CapturePeriod       = 100;
112
113     FileOnlyHelperService helper;
114
115     // Enable the profiling service
116     armnn::profiling::ProfilingService profilingService;
117     profilingService.ResetExternalProfilingOptions(options, true);
118     // Bring the profiling service to the "WaitingForAck" state
119     profilingService.Update();
120     profilingService.Update();
121
122
123     BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck);
124
125     profilingService.Update();
126     // First packet sent will be the SendStreamMetaDataPacket, it's possible though unlikely that it will be sent twice
127     // The second or possibly third packet will be the CounterDirectoryPacket which means the
128     // ConnectionAcknowledgedCommandHandler has set the state to active
129     uint32_t packetCount = 0;
130     while(profilingService.GetCurrentState() != ProfilingState::Active && packetCount < 3)
131     {
132         if(!helper.WaitForPacketsSent())
133         {
134             BOOST_FAIL("Timeout waiting for packets");
135         }
136         packetCount++;
137     }
138
139     BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active);
140     // Minimum test here is to check that the file was created.
141     BOOST_CHECK(boost::filesystem::exists(tempPath.c_str()) == true);
142
143     // Increment a counter.
144     BOOST_CHECK(profilingService.IsCounterRegistered(0) == true);
145     profilingService.IncrementCounterValue(0);
146     BOOST_CHECK(profilingService.GetAbsoluteCounterValue(0) > 0);
147     BOOST_CHECK(profilingService.GetDeltaCounterValue(0) > 0);
148
149     // At this point the profiling service is active and we've activated all the counters. Waiting a collection
150     // period should be enough to have some data in the file.
151
152     // Wait for 1 collection period plus a bit of overhead..
153     helper.WaitForPacketsSent();
154
155     // In order to flush the files we need to gracefully close the profiling service.
156     options.m_EnableProfiling = false;
157     profilingService.ResetExternalProfilingOptions(options, true);
158
159     // The output file size should be greater than 0.
160     BOOST_CHECK(armnnUtils::Filesystem::GetFileSize(tempPath.string().c_str()) > 0);
161
162     // Delete the tmp file.
163     BOOST_CHECK(armnnUtils::Filesystem::Remove(tempPath.string().c_str()));
164 }
165
166 BOOST_AUTO_TEST_SUITE_END()