From 032bc74ca4bc6589a33f23db31accddc5b20baaa Mon Sep 17 00:00:00 2001 From: Finn Williams Date: Wed, 12 Feb 2020 11:02:34 +0000 Subject: IVGCVSW-4338 Implement the Activation of Counters in backends Signed-off-by: Finn Williams Change-Id: I4a2465f06e046f78242ff0a246c651638b205498 --- .../backendsCommon/test/BackendProfilingTests.cpp | 406 ++++++++++++++++++++- 1 file changed, 405 insertions(+), 1 deletion(-) (limited to 'src/backends/backendsCommon/test/BackendProfilingTests.cpp') 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 +#include + +#include +#include #include #include +#include +#include +#include + +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; + + /// 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& selectedCounterIds) + { + boost::ignore_unused(capturePeriod); + boost::ignore_unused(selectedCounterIds); + } + + std::vector GetTimestamps() + { + return m_timestamps; + } + + void ClearTimestamps() + { + m_timestamps.clear(); + } + +private: + std::vector m_timestamps; +}; + +Packet PacketWriter(uint32_t period, std::vector countervalues) +{ + const uint32_t packetId = 0x40000; + uint32_t offset = 0; + uint32_t dataLength = static_cast(4 + countervalues.size() * 2); + std::unique_ptr uniqueData = std::make_unique(dataLength); + unsigned char* data1 = reinterpret_cast(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 cpuBackendProfilingPtr = + std::make_unique(options, profilingService, cpuAccId); + std::unique_ptr gpuBackendProfilingPtr = + std::make_unique(options, profilingService, gpuAccId); + + std::shared_ptr cpuProfilingContextPtr = + std::make_shared(cpuBackendProfilingPtr); + std::shared_ptr gpuProfilingContextPtr = + std::make_shared(gpuBackendProfilingPtr); + + std::unordered_map> 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 cpuCounters{5, 6, 7}; + std::vector gpuCounters{8, 9, 10}; + + // Request only gpu counters + periodicCounterSelectionCommandHandler(PacketWriter(period, gpuCounters)); + periodicCounterCapture.Stop(); + + std::set activeIds = holder.GetCaptureData().GetActiveBackends(); + BOOST_CHECK(activeIds.size() == 1); + BOOST_CHECK(activeIds.find(gpuAccId) != activeIds.end()); + + std::vector 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 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 cpuBackendProfilingPtr = + std::make_unique(options, profilingService, cpuAccId); + + std::shared_ptr cpuProfilingContextPtr = + std::make_shared(cpuBackendProfilingPtr); + + std::unordered_map> 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 -- cgit v1.2.1