diff options
author | Finn Williams <Finn.Williams@arm.com> | 2020-02-12 11:02:34 +0000 |
---|---|---|
committer | Finn Williams <Finn.Williams@arm.com> | 2020-02-14 10:20:00 +0000 |
commit | 032bc74ca4bc6589a33f23db31accddc5b20baaa (patch) | |
tree | 07ae871bc1d667105c7a4b5da2b670b977d5abcb /src/backends/backendsCommon | |
parent | c1536d69c1468514425e143b0578656f51598b94 (diff) | |
download | armnn-032bc74ca4bc6589a33f23db31accddc5b20baaa.tar.gz |
IVGCVSW-4338 Implement the Activation of Counters in backends
Signed-off-by: Finn Williams <Finn.Williams@arm.com>
Change-Id: I4a2465f06e046f78242ff0a246c651638b205498
Diffstat (limited to 'src/backends/backendsCommon')
-rw-r--r-- | src/backends/backendsCommon/test/BackendProfilingTests.cpp | 406 | ||||
-rw-r--r-- | src/backends/backendsCommon/test/MockBackend.hpp | 32 |
2 files changed, 434 insertions, 4 deletions
diff --git a/src/backends/backendsCommon/test/BackendProfilingTests.cpp b/src/backends/backendsCommon/test/BackendProfilingTests.cpp index fc21730651..6e4a020fa5 100644 --- a/src/backends/backendsCommon/test/BackendProfilingTests.cpp +++ b/src/backends/backendsCommon/test/BackendProfilingTests.cpp @@ -3,14 +3,108 @@ // SPDX-License-Identifier: MIT // +#include "CounterDirectory.hpp" +#include "CounterIdMap.hpp" +#include "Holder.hpp" #include "MockBackend.hpp" #include "MockBackendId.hpp" -#include "Runtime.hpp" +#include "PeriodicCounterCapture.hpp" +#include "PeriodicCounterSelectionCommandHandler.hpp" +#include "ProfilingStateMachine.hpp" +#include "ProfilingUtils.hpp" +#include "RequestCounterDirectoryCommandHandler.hpp" #include <armnn/BackendId.hpp> +#include <armnn/Logging.hpp> + +#include <boost/algorithm/string.hpp> +#include <boost/numeric/conversion/cast.hpp> #include <boost/test/unit_test.hpp> #include <vector> +#include <cstdint> +#include <limits> +#include <backends/BackendProfiling.hpp> + +using namespace armnn::profiling; + +class ReadCounterVals : public IReadCounterValues +{ + virtual bool IsCounterRegistered(uint16_t counterUid) const override + { + return (counterUid > 4 && counterUid < 11); + } + virtual uint16_t GetCounterCount() const override + { + return 1; + } + virtual uint32_t GetCounterValue(uint16_t counterUid) const override + { + return counterUid; + } +}; + +class MockBackendSendCounterPacket : public ISendCounterPacket +{ +public: + using IndexValuePairsVector = std::vector<CounterValue>; + + /// Create and write a StreamMetaDataPacket in the buffer + virtual void SendStreamMetaDataPacket() {} + + /// Create and write a CounterDirectoryPacket from the parameters to the buffer. + virtual void SendCounterDirectoryPacket(const ICounterDirectory& counterDirectory) + { + boost::ignore_unused(counterDirectory); + } + + /// Create and write a PeriodicCounterCapturePacket from the parameters to the buffer. + virtual void SendPeriodicCounterCapturePacket(uint64_t timestamp, const IndexValuePairsVector& values) + { + m_timestamps.emplace_back(Timestamp{timestamp, values}); + } + + /// Create and write a PeriodicCounterSelectionPacket from the parameters to the buffer. + virtual void SendPeriodicCounterSelectionPacket(uint32_t capturePeriod, + const std::vector<uint16_t>& selectedCounterIds) + { + boost::ignore_unused(capturePeriod); + boost::ignore_unused(selectedCounterIds); + } + + std::vector<Timestamp> GetTimestamps() + { + return m_timestamps; + } + + void ClearTimestamps() + { + m_timestamps.clear(); + } + +private: + std::vector<Timestamp> m_timestamps; +}; + +Packet PacketWriter(uint32_t period, std::vector<uint16_t> countervalues) +{ + const uint32_t packetId = 0x40000; + uint32_t offset = 0; + uint32_t dataLength = static_cast<uint32_t>(4 + countervalues.size() * 2); + std::unique_ptr<unsigned char[]> uniqueData = std::make_unique<unsigned char[]>(dataLength); + unsigned char* data1 = reinterpret_cast<unsigned char*>(uniqueData.get()); + + WriteUint32(data1, offset, period); + offset += 4; + for (auto countervalue : countervalues) + { + WriteUint16(data1, offset, countervalue); + offset += 2; + } + + return {packetId, dataLength, uniqueData}; +} + BOOST_AUTO_TEST_SUITE(BackendProfilingTestSuite) BOOST_AUTO_TEST_CASE(BackendProfilingCounterRegisterMockBackendTest) @@ -38,4 +132,314 @@ BOOST_AUTO_TEST_CASE(BackendProfilingCounterRegisterMockBackendTest) profilingService.ResetExternalProfilingOptions(options.m_ProfilingOptions, true); } +BOOST_AUTO_TEST_CASE(TestBackendCounters) +{ + Holder holder; + PacketVersionResolver packetVersionResolver; + ProfilingStateMachine stateMachine; + ReadCounterVals readCounterVals; + CounterIdMap counterIdMap; + MockBackendSendCounterPacket sendCounterPacket; + + const armnn::BackendId cpuAccId(armnn::Compute::CpuAcc); + const armnn::BackendId gpuAccId(armnn::Compute::GpuAcc); + + armnn::IRuntime::CreationOptions options; + options.m_ProfilingOptions.m_EnableProfiling = true; + + armnn::profiling::ProfilingService& profilingService = armnn::profiling::ProfilingService::Instance(); + + std::unique_ptr<armnn::profiling::IBackendProfiling> cpuBackendProfilingPtr = + std::make_unique<BackendProfiling>(options, profilingService, cpuAccId); + std::unique_ptr<armnn::profiling::IBackendProfiling> gpuBackendProfilingPtr = + std::make_unique<BackendProfiling>(options, profilingService, gpuAccId); + + std::shared_ptr<armnn::profiling::IBackendProfilingContext> cpuProfilingContextPtr = + std::make_shared<armnn::MockBackendProfilingContext>(cpuBackendProfilingPtr); + std::shared_ptr<armnn::profiling::IBackendProfilingContext> gpuProfilingContextPtr = + std::make_shared<armnn::MockBackendProfilingContext>(gpuBackendProfilingPtr); + + std::unordered_map<armnn::BackendId, + std::shared_ptr<armnn::profiling::IBackendProfilingContext>> backendProfilingContexts; + + backendProfilingContexts[cpuAccId] = cpuProfilingContextPtr; + backendProfilingContexts[gpuAccId] = gpuProfilingContextPtr; + + uint16_t globalId = 5; + + counterIdMap.RegisterMapping(globalId++, 0, cpuAccId); + counterIdMap.RegisterMapping(globalId++, 1, cpuAccId); + counterIdMap.RegisterMapping(globalId++, 2, cpuAccId); + + counterIdMap.RegisterMapping(globalId++, 0, gpuAccId); + counterIdMap.RegisterMapping(globalId++, 1, gpuAccId); + counterIdMap.RegisterMapping(globalId++, 2, gpuAccId); + + backendProfilingContexts[cpuAccId] = cpuProfilingContextPtr; + backendProfilingContexts[gpuAccId] = gpuProfilingContextPtr; + + PeriodicCounterCapture periodicCounterCapture(holder, sendCounterPacket, readCounterVals, + counterIdMap, backendProfilingContexts); + + uint16_t maxArmnnCounterId = 4; + + PeriodicCounterSelectionCommandHandler periodicCounterSelectionCommandHandler(0, + 4, + packetVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(), + backendProfilingContexts, + counterIdMap, + holder, + maxArmnnCounterId, + periodicCounterCapture, + readCounterVals, + sendCounterPacket, + stateMachine); + + stateMachine.TransitionToState(ProfilingState::NotConnected); + stateMachine.TransitionToState(ProfilingState::WaitingForAck); + stateMachine.TransitionToState(ProfilingState::Active); + + uint32_t period = 12345u; + + std::vector<uint16_t> cpuCounters{5, 6, 7}; + std::vector<uint16_t> gpuCounters{8, 9, 10}; + + // Request only gpu counters + periodicCounterSelectionCommandHandler(PacketWriter(period, gpuCounters)); + periodicCounterCapture.Stop(); + + std::set<armnn::BackendId> activeIds = holder.GetCaptureData().GetActiveBackends(); + BOOST_CHECK(activeIds.size() == 1); + BOOST_CHECK(activeIds.find(gpuAccId) != activeIds.end()); + + std::vector<Timestamp> recievedTimestamp = sendCounterPacket.GetTimestamps(); + + BOOST_CHECK(recievedTimestamp[0].timestamp == period); + BOOST_CHECK(recievedTimestamp.size() == 1); + BOOST_CHECK(recievedTimestamp[0].counterValues.size() == gpuCounters.size()); + for (unsigned long i=0; i< gpuCounters.size(); ++i) + { + BOOST_CHECK(recievedTimestamp[0].counterValues[i].counterId == gpuCounters[i]); + BOOST_CHECK(recievedTimestamp[0].counterValues[i].counterValue == i + 1u); + } + sendCounterPacket.ClearTimestamps(); + + // Request only cpu counters + periodicCounterSelectionCommandHandler(PacketWriter(period, cpuCounters)); + periodicCounterCapture.Stop(); + + activeIds = holder.GetCaptureData().GetActiveBackends(); + BOOST_CHECK(activeIds.size() == 1); + BOOST_CHECK(activeIds.find(cpuAccId) != activeIds.end()); + + recievedTimestamp = sendCounterPacket.GetTimestamps(); + + BOOST_CHECK(recievedTimestamp[0].timestamp == period); + BOOST_CHECK(recievedTimestamp.size() == 1); + BOOST_CHECK(recievedTimestamp[0].counterValues.size() == cpuCounters.size()); + for (unsigned long i=0; i< cpuCounters.size(); ++i) + { + BOOST_CHECK(recievedTimestamp[0].counterValues[i].counterId == cpuCounters[i]); + BOOST_CHECK(recievedTimestamp[0].counterValues[i].counterValue == i + 1u); + } + sendCounterPacket.ClearTimestamps(); + + // Request combination of cpu & gpu counters with new period + period = 12222u; + periodicCounterSelectionCommandHandler(PacketWriter(period, {cpuCounters[0], gpuCounters[2], + gpuCounters[1], cpuCounters[1], gpuCounters[0]})); + periodicCounterCapture.Stop(); + + activeIds = holder.GetCaptureData().GetActiveBackends(); + BOOST_CHECK(activeIds.size() == 2); + BOOST_CHECK(activeIds.find(cpuAccId) != activeIds.end()); + BOOST_CHECK(activeIds.find(gpuAccId) != activeIds.end()); + + recievedTimestamp = sendCounterPacket.GetTimestamps(); + + BOOST_CHECK(recievedTimestamp[0].timestamp == period); + BOOST_CHECK(recievedTimestamp[1].timestamp == period); + + BOOST_CHECK(recievedTimestamp.size() == 2); + BOOST_CHECK(recievedTimestamp[0].counterValues.size() == 2); + BOOST_CHECK(recievedTimestamp[1].counterValues.size() == gpuCounters.size()); + + BOOST_CHECK(recievedTimestamp[0].counterValues[0].counterId == cpuCounters[0]); + BOOST_CHECK(recievedTimestamp[0].counterValues[0].counterValue == 1u); + BOOST_CHECK(recievedTimestamp[0].counterValues[1].counterId == cpuCounters[1]); + BOOST_CHECK(recievedTimestamp[0].counterValues[1].counterValue == 2u); + + for (unsigned long i=0; i< gpuCounters.size(); ++i) + { + BOOST_CHECK(recievedTimestamp[1].counterValues[i].counterId == gpuCounters[i]); + BOOST_CHECK(recievedTimestamp[1].counterValues[i].counterValue == i + 1u); + } + + sendCounterPacket.ClearTimestamps(); + + // Request all counters + std::vector<uint16_t> counterValues; + counterValues.insert(counterValues.begin(), cpuCounters.begin(), cpuCounters.end()); + counterValues.insert(counterValues.begin(), gpuCounters.begin(), gpuCounters.end()); + + periodicCounterSelectionCommandHandler(PacketWriter(period, counterValues)); + periodicCounterCapture.Stop(); + + activeIds = holder.GetCaptureData().GetActiveBackends(); + BOOST_CHECK(activeIds.size() == 2); + BOOST_CHECK(activeIds.find(cpuAccId) != activeIds.end()); + BOOST_CHECK(activeIds.find(gpuAccId) != activeIds.end()); + + recievedTimestamp = sendCounterPacket.GetTimestamps(); + + BOOST_CHECK(recievedTimestamp[0].counterValues.size() == cpuCounters.size()); + for (unsigned long i=0; i< cpuCounters.size(); ++i) + { + BOOST_CHECK(recievedTimestamp[0].counterValues[i].counterId == cpuCounters[i]); + BOOST_CHECK(recievedTimestamp[0].counterValues[i].counterValue == i + 1u); + } + + BOOST_CHECK(recievedTimestamp[1].counterValues.size() == gpuCounters.size()); + for (unsigned long i=0; i< gpuCounters.size(); ++i) + { + BOOST_CHECK(recievedTimestamp[1].counterValues[i].counterId == gpuCounters[i]); + BOOST_CHECK(recievedTimestamp[1].counterValues[i].counterValue == i + 1u); + } + sendCounterPacket.ClearTimestamps(); + + // Request random counters with duplicates and invalid counters + counterValues = {0, 0, 200, cpuCounters[2], gpuCounters[0],3 ,30, cpuCounters[0],cpuCounters[2], gpuCounters[1], 3, + 90, 0, 30, gpuCounters[0], gpuCounters[0]}; + + periodicCounterSelectionCommandHandler(PacketWriter(period, counterValues)); + periodicCounterCapture.Stop(); + + activeIds = holder.GetCaptureData().GetActiveBackends(); + BOOST_CHECK(activeIds.size() == 2); + BOOST_CHECK(activeIds.find(cpuAccId) != activeIds.end()); + BOOST_CHECK(activeIds.find(gpuAccId) != activeIds.end()); + + recievedTimestamp = sendCounterPacket.GetTimestamps(); + + BOOST_CHECK(recievedTimestamp.size() == 2); + + BOOST_CHECK(recievedTimestamp[0].counterValues.size() == 2); + + BOOST_CHECK(recievedTimestamp[0].counterValues[0].counterId == cpuCounters[0]); + BOOST_CHECK(recievedTimestamp[0].counterValues[0].counterValue == 1u); + BOOST_CHECK(recievedTimestamp[0].counterValues[1].counterId == cpuCounters[2]); + BOOST_CHECK(recievedTimestamp[0].counterValues[1].counterValue == 3u); + + BOOST_CHECK(recievedTimestamp[1].counterValues.size() == 2); + + BOOST_CHECK(recievedTimestamp[1].counterValues[0].counterId == gpuCounters[0]); + BOOST_CHECK(recievedTimestamp[1].counterValues[0].counterValue == 1u); + BOOST_CHECK(recievedTimestamp[1].counterValues[1].counterId == gpuCounters[1]); + BOOST_CHECK(recievedTimestamp[1].counterValues[1].counterValue == 2u); + + sendCounterPacket.ClearTimestamps(); + + // Request no counters + periodicCounterSelectionCommandHandler(PacketWriter(period, {})); + periodicCounterCapture.Stop(); + + activeIds = holder.GetCaptureData().GetActiveBackends(); + BOOST_CHECK(activeIds.size() == 0); + + recievedTimestamp = sendCounterPacket.GetTimestamps(); + BOOST_CHECK(recievedTimestamp.size() == 0); + + sendCounterPacket.ClearTimestamps(); + + // Request period of zero + periodicCounterSelectionCommandHandler(PacketWriter(0, counterValues)); + periodicCounterCapture.Stop(); + + activeIds = holder.GetCaptureData().GetActiveBackends(); + BOOST_CHECK(activeIds.size() == 0); + + recievedTimestamp = sendCounterPacket.GetTimestamps(); + BOOST_CHECK(recievedTimestamp.size() == 0); +} + +BOOST_AUTO_TEST_CASE(TestBackendCounterLogging) +{ + std::stringstream ss; + + struct StreamRedirector + { + public: + StreamRedirector(std::ostream &stream, std::streambuf *newStreamBuffer) + : m_Stream(stream), m_BackupBuffer(m_Stream.rdbuf(newStreamBuffer)) + {} + + ~StreamRedirector() + { m_Stream.rdbuf(m_BackupBuffer); } + + private: + std::ostream &m_Stream; + std::streambuf *m_BackupBuffer; + }; + + Holder holder; + PacketVersionResolver packetVersionResolver; + ProfilingStateMachine stateMachine; + ReadCounterVals readCounterVals; + StreamRedirector redirect(std::cout, ss.rdbuf()); + CounterIdMap counterIdMap; + MockBackendSendCounterPacket sendCounterPacket; + + const armnn::BackendId cpuAccId(armnn::Compute::CpuAcc); + const armnn::BackendId gpuAccId(armnn::Compute::GpuAcc); + + armnn::IRuntime::CreationOptions options; + options.m_ProfilingOptions.m_EnableProfiling = true; + + armnn::profiling::ProfilingService& profilingService = armnn::profiling::ProfilingService::Instance(); + + std::unique_ptr<armnn::profiling::IBackendProfiling> cpuBackendProfilingPtr = + std::make_unique<BackendProfiling>(options, profilingService, cpuAccId); + + std::shared_ptr<armnn::profiling::IBackendProfilingContext> cpuProfilingContextPtr = + std::make_shared<armnn::MockBackendProfilingContext>(cpuBackendProfilingPtr); + + std::unordered_map<armnn::BackendId, + std::shared_ptr<armnn::profiling::IBackendProfilingContext>> backendProfilingContexts; + + uint16_t globalId = 5; + counterIdMap.RegisterMapping(globalId, 0, cpuAccId); + backendProfilingContexts[cpuAccId] = cpuProfilingContextPtr; + + PeriodicCounterCapture periodicCounterCapture(holder, sendCounterPacket, readCounterVals, + counterIdMap, backendProfilingContexts); + + uint16_t maxArmnnCounterId = 4; + + PeriodicCounterSelectionCommandHandler periodicCounterSelectionCommandHandler(0, + 4, + packetVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(), + backendProfilingContexts, + counterIdMap, + holder, + maxArmnnCounterId, + periodicCounterCapture, + readCounterVals, + sendCounterPacket, + stateMachine); + + stateMachine.TransitionToState(ProfilingState::NotConnected); + stateMachine.TransitionToState(ProfilingState::WaitingForAck); + stateMachine.TransitionToState(ProfilingState::Active); + + uint32_t period = 15939u; + + armnn::SetAllLoggingSinks(true, false, false); + SetLogFilter(armnn::LogSeverity::Warning); + periodicCounterSelectionCommandHandler(PacketWriter(period, {5})); + periodicCounterCapture.Stop(); + SetLogFilter(armnn::LogSeverity::Fatal); + + BOOST_CHECK(boost::contains(ss.str(), "ActivateCounters example test error")); +} + BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file diff --git a/src/backends/backendsCommon/test/MockBackend.hpp b/src/backends/backendsCommon/test/MockBackend.hpp index 21ce7ab85d..641d67ff24 100644 --- a/src/backends/backendsCommon/test/MockBackend.hpp +++ b/src/backends/backendsCommon/test/MockBackend.hpp @@ -13,6 +13,8 @@ #include <armnn/backends/IBackendInternal.hpp> #include <armnn/backends/OptimizationViews.hpp> #include <backendsCommon/LayerSupportBase.hpp> +#include <armnn/backends/profiling/IBackendProfiling.hpp> +#include <backends/BackendProfiling.hpp> namespace armnn { @@ -53,6 +55,7 @@ class MockBackendProfilingContext : public profiling::IBackendProfilingContext public: MockBackendProfilingContext(IBackendInternal::IBackendProfilingPtr& backendProfiling) : m_BackendProfiling(backendProfiling) + , m_CapturePeriod(0) {} ~MockBackendProfilingContext() = default; @@ -81,19 +84,42 @@ public: return nextMaxGlobalCounterId; } - void ActivateCounters(uint32_t, const std::vector<uint16_t>&) - {} + Optional<std::string> ActivateCounters(uint32_t capturePeriod, const std::vector<uint16_t>& counterIds) + { + if ( capturePeriod == 0 || counterIds.size() == 0) + { + m_ActiveCounters.clear(); + } + else if (capturePeriod == 15939u) + { + return armnn::Optional<std::string>("ActivateCounters example test error"); + } + m_CapturePeriod = capturePeriod; + m_ActiveCounters = counterIds; + return armnn::Optional<std::string>(); + } std::vector<profiling::Timestamp> ReportCounterValues() { - return std::vector<profiling::Timestamp>(); + std::vector<profiling::CounterValue> counterValues; + + for(auto counterId : m_ActiveCounters) + { + counterValues.emplace_back(profiling::CounterValue{counterId, counterId+1u}); + } + + uint64_t timestamp = m_CapturePeriod; + return {profiling::Timestamp{timestamp, counterValues}}; } void EnableProfiling(bool) {} private: + IBackendInternal::IBackendProfilingPtr& m_BackendProfiling; + uint32_t m_CapturePeriod; + std::vector<uint16_t> m_ActiveCounters; }; class MockBackend : public IBackendInternal |